2012-02-26 16 views
5

Próbuję zrozumieć, w jaki sposób działa ARC, i o ile wiem, powinienem robić coś złego tutaj. Jest to kod używam:iOS ARC - słabe i silne właściwości

Interfejs:

@interface ViewController : UIViewController{ 

} 

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

Realizacja:

- (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) ; 
} 

Po wykonaniu tego, otrzymuję:

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! 

Jeśli Nie myliłem się, ponieważ myPointer jest słaby, nie powinien zatrzymywać zawartości obiektu. Powinno to wskazywać zero zamiast "Hello World!".

Co robię źle?

następującą odpowiedź Caleba, ja stworzyliśmy kolejny słaby wskaźnik, patrz poniższy kod:

- (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) ; 
} 

Chodzi o to, że ja wciąż mam tę samą odpowiedź Kiedyś miałem:

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! 

Odpowiedz

8

Jak zauważył Caleb, używanie stałego NSString do tego przykładu nie jest dobrym pomysłem.

Najprostszym sposobem utworzenia obiektu ciąg w kodzie źródłowym jest użycie celu C @ "..." konstrukt:

NSString * Temp = @ "/ tmp/zera"; Zauważ, że przy tworzeniu stałej stałej powinieneś unikać używania tylko 7-bitowych znaków ASCII . Taki obiekt jest tworzony podczas kompilacji i istnieje w trakcie wykonywania programu. Kompilator sprawia, że ​​takie obiekty są stałe unikalne w poszczególnych modułach i nigdy nie są przydzielane, , chociaż można je zachować i zwolnić tak jak każdy inny obiekt. Ci można również wysyłać wiadomości bezpośrednio na ciąg stały, jak to zrobić żadnej inny napis:

BOOL samo = [@ „porównanie” isEqualToString: myString];

The documentation wyjaśnia, że ​​stałe ciągi nigdy nie znikną.

Spróbuj użyć czegoś innego do eksperymentu. Próbowałem NSObject i dało oczekiwane rezultaty.

Interfejs:

@interface ViewController : UIViewController 

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

@end 

Realizacja:

@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 

Słabe wskaźniki są ustawione na zero, gdy nie ma silne wskaźniki do pamięci zgodnie z opisem w dokumentacji - Apple Developer lub llvm.

__weak określa odniesienie, które nie utrzymuje żywego obiektu odniesienia. Wartość słabego odniesienia jest ustawiana na zero, gdy nie ma silnych odniesień do obiektu.

+0

Znakomita odpowiedź, wielkie dzięki. – RGML

5

To powinno pokazać zero zamiast "Hello World!".

Stałe ciągi nigdy nie są anulowane, więc Twój "@" Hello World! " nigdy nie odejdzie. Dlatego twoje słabe odniesienie nigdy nie jest ustawione na zero.

+0

Dzięki za odpowiedź Caleb. To ma sens, jednak stworzyłem kolejny słaby wskaźnik, aby sprawdzić, co mówisz. Niestety, jak widać, to nie działa. – RGML

+0

@Arkyxperience Czego oczekujesz? – Caleb

+5

Słabe odniesienia są ustawiane na zero, gdy ich cel jest zwolniony. Jest to cecha ARC - syntetyzowane słabe właściwości nigdy nie będą trzymały zwisającego wskaźnika. – FellowMD

Powiązane problemy