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ą.
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ą.
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.
Dziękujemy @ JonasG. :-) – liza
Spróbuj tego: Understand memory management under ARC
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).
Dziękuję @Mike Weller – liza
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
Można sprawdzić http://stackoverflow.com/questions/8592289/arc-the-meaning-of-unsafe-unretained –