2013-04-12 15 views
9

Znam definicję unsafe_unretained.Jaka jest korzyść z atrybutu unsafe_unretained?

Nie oczekuję, że ktokolwiek napisze definicję.

Chcę poznać jego użycie na przykładzie i jak to działa z zarządzanie pamięcią.

+0

Można sprawdzić http://stackoverflow.com/questions/8592289/arc-the-meaning-of-unsafe-unretained –

Odpowiedz

23

unsafe_unretained istnieje tylko w ARC. Działa w MRC pod numerem assign. Te właściwości nie zostaną zachowane. Zwykle nie będziecie używać takich właściwości dla delegatów, ponieważ nie potrzebują oni właściciela, który je zatrzyma.

weak właściwości są podobne do unsafe_unretained tylko dlatego, że działają nieco mądrzej. Gdy obiekt przypisany do właściwości zostanie zwolniony, słabe odniesienie automatycznie stanie się nil, aby uniknąć awarii podczas wysyłania wiadomości do tego obiektu (jego adresu pamięci). Nieaktywne właściwości nie działają w ten sposób. Będą zawsze trzymać adres pamięci (chyba że ręcznie go zmienisz), niezależnie od obiektu powiązanego z tym adresem. Słabe odniesienia mogą w takim przypadku zapobiegać awariom, ale wynik nadal nie będzie taki, jak oczekiwano. Jeśli twój kod jest dobrze napisany i zorganizowany, nie powinno to mieć miejsca.

Dlaczego więc miałbyś używać unsafe_unretained zamiast weak? Słabe referencje są dostępne tylko w systemie iOS 5 i nowszych wersjach, więc jeśli tworzysz aplikację ARC kierowaną na system iOS 4, musisz użyć właściwości unsafe_unretained. I znowu, wysyłanie wiadomości do wydanej właściwości nie jest czymś, co chcesz mieć w dowolnym kodzie, więc jeśli twój kod jest dobrze zorganizowany, nie powinieneś mieć z tym żadnych problemów.

+0

Dziękujemy @ JonasG. :-) – liza

1

Wcześniej do ARC, można określić delegata lub innego odniesienia do związku macierzystego nieruchomości jako assign aby zapobiec zachować cykli. Wraz z wprowadzeniem ARC i nowszych kompilatorów użyjesz zamiast tego unsafe_unretained.

Używa się go zatem za każdym razem, gdy nie jest wymagane posiadanie referencji, a gdy nie jest potrzebne lub nie chce się używać nowego typu referencyjnego weak (który zeruje odniesienie, gdy jest zwalniany).

+0

Dziękuję @Mike Weller – liza

0

Oto szczególny przypadek użycia dla unsafe_unretained. Powiedzmy, że dwie klasy odnoszą się do siebie, jeden kierunek jest silny, a drugi słabszy. Podczas dealloc pierwszej klasy słabe odniesienie do niej z drugiej klasy będzie już zerowe, uniemożliwiając prawidłowe porządkowanie. Zastąpienie tego słabego odniesienia referencją unsafe_unretained. Zobacz przykładowy kod poniżej:

@class Foo; 

@interface Bar: NSObject 

//Replacing weak with unsafe_unretained prevents this property from becoming nil during Foo.dealloc 
@property (nonatomic, weak) Foo *foo; 

- (id)initWithFoo:(Foo *)foo; 

@end 

@interface Foo : NSObject 

@property (nonatomic, strong) Bar *bar; 

- (void)startObserving; 
- (void)endObserving; 

@end 

@implementation Bar 

- (id)initWithFoo:(Foo *)foo { 
    if ((self = [super init])) { 
     self.foo = foo; 

     //Start observing 
     [self.foo startObserving]; 
    } 
    return self; 
} 

- (void)dealloc { 
    //Since foo is a weak property, self.foo may actually be nil at this point! See dealloc of class Foo. 
    [self.foo endObserving]; 
} 

@end 

@implementation Foo 

- (id)init { 
    if ((self = [super init])) { 
     self.bar = [[Bar alloc] initWithFoo:self]; 
    } 
    return self; 
} 

- (void)dealloc { 
    //This will trigger the deallocation of bar. However, at this point all weak references to self will return nil already! 
    self.bar = nil; 

    //endObserving is never called, because Bar.foo reference was already nil. 
} 

- (void)startObserving { 
    NSLog(@"Start observing"); 
} 

- (void)endObserving { 
    NSLog(@"End observing"); 
} 

@end 
Powiązane problemy