Red de conocimiento informático - Material del sitio web - Cómo entender lo fuerte y lo débil en Objective-C

Cómo entender lo fuerte y lo débil en Objective-C

En primer lugar, las dos palabras clave fuerte y débil se utilizan para modificar variables, lo que indica que la variable es una referencia fuerte (fuerte) y una referencia débil (débil).

A menudo use esto en nuestros programas Usando código como "[[class alloc]init]", creo que ya está familiarizado con él. Esto es para abrir una parte de la memoria e inicializarla. Entonces el sistema ha abierto esta memoria, ¿cómo la obtenemos?

Obviamente, la memoria recién asignada se asigna a una variable. En el futuro, podremos usar esta variable para operar directamente esta memoria. Entonces existe una diferencia entre asignar la memoria recién asignada a una variable fuerte y una variable débil:

Después de asignar el valor a una variable débil, la memoria se liberará inmediatamente. La memoria asignada a la variable fuerte no se liberará hasta que finalice el ciclo de vida de la variable (las variables que no se modifican con la palabra clave débil se convierten por defecto en variables fuertes).

Mire el siguiente ejemplo:

Agregue una clase Persona con un solo atributo de nombre

[objc] ver copia simple

@ interfaz Persona: NSObject

@property(nonatomic,copy) NSString *name;

@end

La función principal define un zhangSan débil y un Li Si fuerte , es obvio que la memoria especificada por zhangSan se libera inmediatamente después de la ejecución de "zhangSan=[[Person alloc]init]". Imprimimos los atributos de dirección y nombre de las dos variables respectivamente. Podemos ver que zhangSan efectivamente se lanzó y liSi continúa hasta el final del programa.

[objc] ver copia simple

int main(int argc, const charchar * argv[]) {

@autoreleasepool {

__persona débil* zhangSan=[[Persona alloc]init];

zhangSan.name=@"张三"

Persona *liSi=[[Persona alloc]init];

liSi.name=@"李思";

NSLog(@"%p----%p",zhangSan,liSi

); NSLog(@"%@----%@",zhangSan.name,liSi.name);

}

devuelve 0

} <; /p>

Podemos entenderlo de esta manera. La memoria asignada es como una vaca. Debe estar sujeta con una cuerda fuerte y fuerte. Si se usa una cuerda delgada y débil, la vaca podría quedar cautiva. Rompe la cuerda y escapa en cualquier momento.

El otro extremo de la cuerda está fijado a un objeto que podemos ver y alcanzar (es decir, nuestra variable. Seguimos la cuerda sobre este objeto y buscamos a tientas si todavía está allí). o no depende de la cuerda que utilices.

Entonces, dado que la memoria de variables de tipo débil se libera después de su asignación, ¿para qué sirve? Veamos el siguiente ejemplo nuevamente

Primero asigne la memoria asignada a una variable fuerte y luego asigne la variable fuerte a una variable débil. De esta manera, las direcciones de las dos personas son obviamente las mismas. el atributo de nombre también es el mismo.

Esto es como atar a la vaca con una cuerda fuerte primero para que no se escape, y luego atar a la vaca con una cuerda débil para que la vaca pueda ser encontrada a lo largo de la cuerda débil. Obviamente, si rompemos la cuerda fuerte, la cuerda débil naturalmente no podrá tirar de la vaca. Por ejemplo, el siguiente ejemplo:

"liSi" se declara dentro de un par de llaves, lo que indica que solo es válido dentro de las llaves, a excepción de las llaves, el objeto con la cuerda ya no está. entonces la vaca se liberará naturalmente. Las ataduras de la cuerda se escaparán, por lo que es imposible para ti obtener "wangWu" y encontrar la vaca (la memoria y el valor en la memoria). Entonces, si hay varias cuerdas fuertes atando al ganado, debes saber lo que está pasando.

Ata una vaca con dos cuerdas fuertes, aunque una se haya ido, la vaca aún se puede encontrar con la otra.

En este punto, en realidad no hemos mencionado el uso del mecanismo de variable de tipo débil. Veamos el siguiente ejemplo

1. Personalice una vista para heredar de UIView. Escriba el método dealloc para ver cuándo se destruye el objeto

[objc] ver copia simple

#import "myView.h"

@implementation myView

-(void)dealloc

{

NSLog(@"El objeto fue destruido"); @ end

2. Cuando el programa requiere la vista principal, agregamos la vista personalizada a la vista principal, agregamos un botón y escuchamos los eventos de clic.

[objc] ver copia simple

- (void)viewDidLoad {

[super viewDidLoad]

//Crear vista personalizada;

myView *view=[[myView alloc]init];

view.frame=CGRectMake(50, 50, 200, 200); backgroundColor=[UIColor redColor];

UILabel *msgLabel=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 20)]

msgLabel.text=@ " Esta es una vista";

[view addSubview:msgLabel];

//Agregar a la vista

[self.view addSubview:view]; < / p>

//Agregar botón

UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(100, 260, 100, 80)]

[btn setTitle : @"Eliminar subvista" forState:UIControlStateNormal];

[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]

[btn addTarget:self action:@selector( btnClick) forControlEvents; :UIControlEventTouchUpInside];

[self.view addSubview:btn]

}

-(void)btnClick

{

NSLog(@"Botón hecho clic");

}

El efecto que quiero es: hacer clic en el botón para eliminar la subvista y el programa se ejecutará. Nunca uses esta vista.

Aquí pienso en dos formas de obtener esta vista y luego eliminarla del control principal.

La primera forma: este método obviamente puede cumplir con ese requisito. el resultado impreso. El objeto también se destruye después de que la subvista se elimina del controlador principal. Sin embargo, este no es nuestro método más utilizado. Puede haber muchas subvistas en el control principal, lo cual es muy ineficiente y el código no es conciso.

[objc] ver copia simple

-(void)btnClick

{

para (UIView *subView en self.view. subvistas) {

if ([subView isKindOfClass:[myView class]]) {

[subView removeFromSuperview]

}

; }

NSLog(@"Botón hecho clic");

}

Segundo: Agregamos un atributo al controlador que apunta a nuestra subvista. Hay dos posibilidades para este atributo, una es fuerte y la otra es débil. Probemos primero con fuerza.

Como se puede ver en los resultados, la subvista se elimina cuando se hace clic en el botón, pero el objeto no se destruye. Todavía está en la memoria (puede intentar agregar otro botón para imprimir self.testView), que no es el efecto que queremos.

Vamos a probar con débil. Solo necesitamos cambiar de fuerte a débil en el lugar donde se declara la variable, y los demás lugares permanecen sin cambios. Se puede ver en los resultados de la ejecución: la subvista se elimina y la variable se destruye.

¿Por qué no se libera la memoria asignada cuando no agregamos el atributo fuerte, pero aún podemos encontrarla a través del bucle for? Cabe señalar que cuando se agrega una vista A a otra vista B, las subvistas de B hacen referencia fuerte a A (hay una cuerda fuerte que tira de ella), por lo que usamos un atributo fuerte para tirar de ella. Si es así, se liberará naturalmente. sólo cuando ambas cuerdas están rotas.

Quizás ahora entiendas un poco más sobre fuertes y débiles