por qué débil para la propiedad y __ débil por ejemplo variable se comportan de manera diferente

Sé que los modificadores utilizados son fuertes y débiles en las declaraciones de properties, mientras que __strong y __weak se utilizan en las declaraciones de variables de instancia … fuerte dice que mantener el object en la memory siempre que sea dueño de él y débil dice que mantener el object en la memory como Mientras alguien más tenga una fuerte reference a eso … ¿verdad? pero no entiendo por qué es débil para la propiedad y __disfruta, por ejemplo, la variable se comporta de manera diferente? Esto es lo que me preguntaba …

@interface DemoViewController (){ __weak NSArray *weakArray; __strong NSArray *strongArray; __weak NSString *weakString; __strong NSString *strongString; } @property (weak) NSString *weakStringProperty; @property (strong) NSString *strongStringProperty; @property (weak) NSArray *weakArrayProperty; @property (strong) NSArray *strongArrayProperty; @end @implementation DemoViewController - (void)viewDidLoad { [super viewDidLoad]; strongArray = [[NSArray alloc] initWithObjects:@"one",@"two", nil]; weakArray = strongArray; NSLog(@"Round:1 strongArray is %@.", strongArray); NSLog(@"Round:1 weakArray is %@.", weakArray); strongArray = nil; NSLog(@"Round:2 strongArray is %@.", strongArray); NSLog(@"Round:2 weakArray is %@.", weakArray); self.strongArrayProperty = [[NSArray alloc] initWithObjects:@"one",@"two", nil]; self.weakArrayProperty = self.strongArrayProperty; NSLog(@"Round:1 strongArrayProperty is %@.", self.strongArrayProperty); NSLog(@"Round:1 weakArrayProperty is %@.", self.weakArrayProperty); self.strongArrayProperty = nil; NSLog(@"Round:2 strongArrayProperty is %@.", self.strongArrayProperty); NSLog(@"Round:2 weakArrayProperty is %@.", self.weakArrayProperty); strongString = [[NSString alloc]initWithFormat:@"instanceVariable"]; weakString = strongString; NSLog(@"Round:1 strongString is %@.", strongString); NSLog(@"Round:1 weakString is %@.", weakString); strongString = nil; NSLog(@"Round:2 strongString is %@.", strongString); NSLog(@"Round:2 weakString is %@.", weakString); self.strongStringProperty = [[NSString alloc]initWithFormat:@"Property"]; self.weakStringProperty = self.strongStringProperty; NSLog(@"Round:1 strongStringProperty is %@.", self.strongStringProperty); NSLog(@"Round:1 weakStringProperty is %@.", self.weakStringProperty); self.strongStringProperty = nil; NSLog(@"Round:2 strongStringProperty is %@.", self.strongStringProperty); NSLog(@"Round:2 weakStringProperty is %@.", self.weakStringProperty); } @end 

Y aquí están los loggings resultantes.

 Round:1 strongArray is ( one, two ). Round:1 weakArray is ( one, two ). Round:2 strongArray is (null). Round:2 weakArray is (null). Round:1 strongArrayProperty is ( one, two ). Round:1 weakArrayProperty is ( one, two ). Round:2 strongArrayProperty is (null). Round:2 weakArrayProperty is ( one, two ). —??? Round:1 strongString is instanceVariable. Round:1 weakString is instanceVariable. Round:2 strongString is (null). Round:2 weakString is (null). Round:1 strongStringProperty is Property. Round:1 weakStringProperty is Property. Round:2 strongStringProperty is (null). Round:2 weakStringProperty is Property. ——?? 

Ambas variables de instancia débiles se imprimen (nulo) después de los objects a los que se referían débilmente, se configuran en nil y esto es lo que se esperaba, pero me pregunto por qué tanto las properties débiles weakStringProperty y weakArrayProperty siguen imprimiendo sus valores anteriores y comportándose como si estuvieran apuntando fuertemente hacia strongStringProperty y strongArrayProperty respectivamente?

Gracias 🙂

weakStringProperty no es nil porque Foundation todavía lo retiene.

Cuando llamó [[NSString alloc]initWithFormat:@"Property"] , Foundation decidió internar la cadena como una NSTaggedPointerString que luego retuvo para uso futuro. Puede validar esto iniciando session en la class:

 NSLog(@"kindof: %@", [self.weakStringProperty class]); 

No estoy seguro de qué criterio utiliza el sistema para decidir crear estas cadenas, pero la longitud y la mutabilidad son factores. Cualquiera de los siguientes obtendría el resultado deseado.

 // Longer string self.strongStringProperty = [[NSString alloc]initWithFormat:@"Property la la la"]; // Mutable string self.strongStringProperty = [[NSMutableString alloc]initWithFormat:@"Property"]; 

Tus properties son atómicas, porque no las declaraste no atómicas. Las properties atómicas devuelven un object que se retiene y autorelease, por lo que el object permanecerá en el grupo de autorelease y seguirá siendo retenido hasta que salga del método viewDidLoad.

Cambie por ejemplo a

 @property (weak, nonatomic, readwrite) NSString *weakStringProperty; 

y es más probable que obtenga el resultado esperado. O revise las properties en otro método más adelante, y las properties débiles probablemente serán nulas.

Sin embargo, iOS a menudo crea objects que nunca se publicarán. Por ejemplo, hay un object NSArray vacío que nunca, nunca será lanzado. Lo mismo para muchos objects NSNumber, cadenas cortas, @YES y @NO y otros. No hay garantía de que un object sea desasignado cuando crea que así sería y, por lo tanto, no garantiza que un object débil se vuelva nulo.