2013-04-12 14 views
9

Ich kenne die Definition von unsafe_unretained.Was ist das unsafe_unreaited Attribut?

Also erwarte ich nicht, dass jemand seine Definition schreibt.

Ich möchte seine Verwendung mit Beispiel kennen, und wie es mit Speicherverwaltung funktioniert.

+0

Sie können prüfen, http://stackoverflow.com/questions/8592289/arc-the-meaning-of-unsafe-unretained –

Antwort

23

unsafe_unretained existiert nur in ARC. Es funktioniert wie assign in MRC. Diese Eigenschaften werden nicht beibehalten. Normalerweise sollten Sie solche Eigenschaften für Delegierte verwenden, da sie keinen Eigentümer benötigen, der sie behält.

weak Eigenschaften sind wie unsafe_unretained nur, dass sie ein bisschen schlauer arbeiten. Wenn das der Eigenschaft zugewiesene Objekt freigegeben wird, wird eine schwache Referenz automatisch nil, um Abstürze beim Senden von Nachrichten an dieses Objekt (seine Speicheradresse) zu vermeiden. Unsafe_unreadyed Eigenschaften tun dies nicht. Sie behalten immer die zugewiesene Speicheradresse (es sei denn, Sie ändern sie manuell) unabhängig von dem Objekt, das dieser Adresse zugeordnet ist. Schwache Referenzen können in einem solchen Fall Abstürze verhindern, aber das Ergebnis wird immer noch nicht wie erwartet sein. Wenn Ihr Code gut geschrieben und organisiert ist, sollte dies nicht passieren.

Also warum würden Sie unsafe_unretained statt weak verwenden? Schwache Referenzen sind nur für iOS 5 und höher verfügbar. Wenn Sie also eine ARC-App für iOS 4 erstellen, müssen Sie die Eigenschaften unsafe_unretained verwenden. Und wieder, Senden von Nachrichten an eine freigegebene Eigenschaft ist nichts, was Sie in einem Code haben möchten, also wenn Ihr Code gut organisiert ist, dann sollten Sie keine Probleme damit haben.

+0

Danke @ JonasG. :-) – liza

1

Zuvor ARC, könnte man einen Delegaten angeben oder eine andere Bezugs-to-Mutter Eigenschaft als assign Zyklen beibehalten zu verhindern. Mit der Einführung von ARC und den neueren Compilern würden Sie stattdessen unsafe_unretained verwenden.

Sie verwenden es also immer dann, wenn Sie die Referenz nicht benötigen und wenn Sie den neuen Referenztyp weak nicht benötigen oder verwenden möchten (wodurch die Referenz bei der Freigabe aufgehoben wird).

+0

Danke @ Mike Weller – liza

0

Hier ist ein spezifischer Anwendungsfall für unsafe_unreadyed. Sagen wir zwei Klassen, die sich gegenseitig ansprechen, eine Richtung ist stark und die andere schwach. Während des Deallocs der ersten Klasse ist der schwache Bezug auf ihn von der zweiten Klasse bereits Null, was verhindert, dass eine saubere Säuberung stattfindet. Durch Ersetzen der schwachen Referenz durch eine unsafe_unrepeated-Referenz wird dieses Problem behoben. Sehen Sie das folgende Codebeispiel:

@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 
Verwandte Themen