2012-02-26 11 views
5

Estoy tratando de entender la forma en que funciona ARC, y hasta donde sé, debería estar haciendo algo mal aquí. Este es el código que estoy usando:iOS ARC - propiedades débiles y fuertes

Interfaz:

@interface ViewController : UIViewController{ 

} 

@property (strong, nonatomic) NSString * myString ; 
@property (weak, nonatomic) NSString * myPointer ; 

Implementación:

- (void)viewDidLoad{ 

    [super viewDidLoad]; 
    self.myString = @"Hello world!" ; // myString is strong 
    self.myPointer = self.myString ; // myPointer var is weak 

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];  
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];  
} 

- (void) makeNilMyValue{ 
    self.myString = nil ; 
} 

- (void) printValues{ 
    NSLog(@"myString: %@", self.myString) ; 
    NSLog(@"myPointer: %@", self.myPointer) ; 
} 

Después de ejecutar esto, me sale:

2012-02-26 11:40:41.652 test1[933:207] myString: (null) 

2012-02-26 11:40:41.653 test1[933:207] myPointer: Hello world! 

Si No me equivoco, debido a myPointer es débil, no debe retener el contenido del objeto. Por lo tanto, debería mostrar nil en lugar de "Hello World!".

¿Qué estoy haciendo mal?

siguiente respuesta de Caleb, he creado otro puntero débil, ver código de abajo:

- (void)viewDidLoad{ 
    [super viewDidLoad]; 
    self.myString = @"Hello world!" ; // myString is strong 
    self.myPointer = self.myString ; // myPointer var is weak 
    self.myPointer2 = self.myString ; // myPointer2 var is weak 

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];  
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];  
} 

- (void) makeNilMyValue{ 
    self.myPointer2 = @"value changed!" ; 
    self.myString = nil ; 

} 

- (void) printValues{ 
    NSLog(@"myString: %@", self.myString) ; 
    NSLog(@"myPointer: %@", self.myPointer) ; 
} 

El punto es que todavía me dio la misma respuesta que solía tener:

2012-02-26 12:08:13.426 test1[1333:207] myString: (null) 
2012-02-26 12:08:13.427 test1[1333:207] myPointer: Hello world! 

Respuesta

8

Como señaló Caleb, usar un NSString constante para este ejemplo no es una buena idea.

La forma más sencilla de crear un objeto de cadena en el código fuente es el uso de la @ Objective-C "..." constructo:

NSString * temp = @ "/ tmp/scratch"; Tenga en cuenta que, al crear una constante de cadena de esta manera, debe evitar usar cualquier cosa que no sean los caracteres ASCII de 7 bits. Tal objeto se crea en tiempo de compilación y existe a lo largo de la ejecución de su programa. El compilador hace que dichas constantes de objeto sean únicas por cada módulo, y nunca se desasignan, aunque puede retenerlas y liberarlas como lo hace con cualquier otro objeto. Usted también puede enviar mensajes directamente a una constante de cadena como lo hace con cualquier otra cadena :

BOOL same = [@ "comparison" isEqualToString: myString];

El documentation explica que las cadenas constantes nunca desaparecerán.

Intente utilizar algo más para su experimento. Intenté NSObject y produjo los resultados esperados.

Interfaz:

@interface ViewController : UIViewController 

@property (strong, nonatomic) NSObject * myString; 
@property (weak, nonatomic) NSObject * myPointer; 

@end 

Implementación:

@implementation ViewController 

@synthesize myString = _myString; 
@synthesize myPointer = _myPointer; 

- (void)viewDidLoad{ 

    [super viewDidLoad]; 

    self.myString = [[NSObject alloc] init]; 
    self.myPointer = self.myString; 
    self.myString = nil; 
    NSLog(@"myString: %@", self.myString); 
    NSLog(@"myPointer: %@", self.myPointer); 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 

@end 

punteros débiles se establecen a cero cuando no hay fuertes punteros a la memoria, como se explica en la documentación - Apple Developer o llvm.

__weak especifica una referencia que no mantiene vivo el objeto al que se hace referencia. Una referencia débil se establece en cero cuando no hay referencias fuertes al objeto.

+0

Brillante respuesta, muchas gracias. – RGML

5

Por lo tanto, debería mostrar nil en lugar de "Hello World!".

Las cadenas constantes nunca se desasignan, por lo que su `@" ¡Hola mundo! " nunca desaparece Esta es la razón por la que su referencia débil nunca se establece en cero.

+0

Gracias por su respuesta Caleb. Eso tiene sentido, sin embargo, he creado otro puntero débil para probar lo que dices. Desafortunadamente, como puedes ver, no funciona. – RGML

+0

@Arkyxperience ¿Qué esperas que pase? – Caleb

+5

Las referencias débiles se establecen en nulas cuando su objetivo se desasigna. Esta es una característica de ARC: las propiedades débiles sintetizadas nunca tendrán un puntero colgante. – FellowMD

Cuestiones relacionadas