2013-04-12 33 views
9

我知道unsafe_unretained的定義。unsafe_unretained屬性的用法是什麼?

所以我不期望任何人寫它的定義。

我想知道它的使用與示例,以及它如何與內存管理

+0

您可以檢查 http://stackoverflow.com/questions/8592289/arc-the-meaning-of-unsafe-unretained –

回答

23

unsafe_unretained只存在於ARC中。它在MRC中像assign一樣工作。這些屬性不會被保留。通常情況下,您不會爲代表使用這些屬性,因爲他們不需要擁有這些屬性的所有者。

weak屬性就像unsafe_unretained只是他們工作有點聰明。當分配給該屬性的對象被釋放時,弱引用自動變爲nil,以避免向該對象(其內存地址)發送消息時發生崩潰。 Unsafe_unretained屬性不這樣做。無論與該地址關聯的對象如何,它們將始終保持分配給它的內存地址(除非您手動更改它)。弱引用可以防止在這種情況下崩潰,但結果仍然不會如預期的那樣。如果你的代碼寫得很好,組織起來不應該發生。

那麼,爲什麼你會用unsafe_unretained而不是weak?弱引用僅適用於iOS 5和更高版本,因此如果您要構建定位iOS 4的ARC應用程序,則需要使用unsafe_unretained屬性。再次,發送消息到發佈的屬性不是你想要的任何代碼,所以如果你的代碼組織的很好,那麼你不應該有任何問題。

+0

謝謝@ JonasG。 :-) – liza

1

此前ARC的,一個可以指定一個委託或其他參考對父母財產assign防止保留週期。隨着ARC和較新的編譯器的推出,您將改爲使用unsafe_unretained

因此,只要您不需要擁有該參考,並且您不需要或不想使用新的參考類型(在解除分配時將參考置零),就可以使用它。

+0

謝謝@Mike韋勒 – liza

0

這是一個unsafe_unretained的特定用例。說兩個階級互相參照,一個方向很強,另一個方向弱。在第一堂課的dealloc期間,第二堂課對它的弱引用已經是零,妨礙了正確的清理。用unsafe_unretained引用替換弱引用將解決此問題。請參見下面的代碼示例:

@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