2009-09-07 50 views
8

我一直想知道一些屬性。在使用屬性時,是否需要重寫發佈消息以確保屬性是已發佈的屬性?正在釋放需要Objective-c 2.0屬性的內存嗎?

以下(虛構)例子是否足夠?

@interface MyList : NSObject { 
NSString* operation; 
NSString* link; 
} 
@property (retain) NSString* operation; 
@property (retain) NSString* link; 
@end 

@implementation MyList 
@synthesize operation,link; 
@end 
+1

因爲NSString確認爲NSCopying協議,所以最好使用 @property(copy,readwrite)NSString *操作 另外,如果使用現代運行時,則不需要指定實例變量:它們將會也合成。 要了解更多信息,請搜索Apple的「Objective-C 2.0編程指南」並查找名爲「Property Declaration Attributes」和「Property Implementation Directives」的章節。 – 2009-10-08 11:39:52

+0

+1個很好的問題,正好想着同樣的東西 – andy 2010-12-23 00:43:37

回答

13

你應該總是釋放後盾變量的dealloc:

- (void) dealloc { 
    [operation release]; 
    [link release]; 

    [super dealloc]; 
} 

另一種方式:

- (void) dealloc { 
    self.operation = nil; 
    self.link = nil; 

    [super dealloc]; 
} 

這不是首選方式釋放對象,但如果您使用合成的支持變量,它是唯一的方法來做到這一點。

注意:要清楚爲什麼這個作品,讓我們來看看合成實施二傳手爲鏈接財產,以及當它被設置爲情況:

- (void) setLink:(MyClass *) value { 
    [value retain]; // calls [nil retain], which does nothing 
    [link release]; // releases the backing variable (ivar) 
    link = value; // sets the backing variable (ivar) to nil 
} 

所以淨效應是它會釋放伊娃。

+1

實際上,如果你使用的是合成的ivars(即,你聲明屬性而不是對應的ivar),那麼將爲你生成一個ivar。看到我的問題在這裏:http://stackoverflow.com/questions/1283419 – 2009-09-07 15:34:51

+3

一些編譯器沒有合成伊娃。在第一個支持合成ivars的編譯器發佈之後,這個問題就解決了。因此混亂。 – bbum 2009-09-07 17:24:47

+0

@bbum有用的信息!謝謝澄清。 – 2009-09-07 18:21:26

1

不,您覆蓋-dealloc方法。是的,如果你不釋放你的屬性(或者說支持ivars),你將會泄漏。因此,在這裏你的@implementation你應該有類似

- (void)dealloc { 
    [operation release]; 
    [link release]; 
    [super dealloc]; 
} 
3

非GC申請,是的。通常分配零而不是釋放ivars。 我最好的經驗是發佈用init初始化的ivars,並將nil分配給保留和複製模式的屬性。

在你的情況我會分配零

- (void) dealloc { 
    self.operation = nil; 
    self.link = nil; 
    [super dealloc]; 
} 
+1

這是唯一正確的方法。 – 2009-09-07 14:10:47

+1

@gs不正確。您可以釋放伊娃,並將它們直接設置爲零。在極少數情況下使用訪問器會產生奇怪的副作用。如果你在一個對象上觀察一個屬性,並且該對象被設置爲nil,那麼你的觀察者可能試圖從obj獲取其他信息,但是如果set-to-nil發生在-dealloc中,可能會發生奇怪的事情。 – 2009-09-07 15:36:55

+0

這是語法的怪癖。人們希望合成或隱含的「@properties_release();」可以在將來的語言規範中添加到dealloc方法中。如果Objective-C 2.0將成爲所有人的所有東西,那麼推薦像accessor-syntax這樣的東西似乎很奇怪,然後必須對析構函數中的觀察者和屬性訪問器發出警告。 – 2010-03-31 22:58:11

1

合成屬性只創建getter和setter方法,以及當對象被釋放爲此不會釋放伊娃。你需要自己釋放伊娃。

+1

這隻適用於聲明的屬性,不*使用默認(分配)屬性。搜索Apple的「Objective-c 2.0編程指南」並閱讀「聲明的屬性」一節,特別是關於dealloc的部分。 我引用:「然而,聲明的屬性提供了一種有用的方法來交叉檢查dealloc方法的實現:您可以在頭文件中查找所有屬性聲明,並確保未標記爲assign的對象屬性被釋放,而那些標記爲分配的內容不會被釋放。「 – 2009-10-08 11:30:10

2

做到這一點,最好的辦法是:

- (void)dealloc { 
    [operation release], operation = nil; 
    [link release], link = nil; 

    [super dealloc]; 
} 

這確實是更方便的使用所產生的setter方法

self.operation = nil; 

但在被皺起了眉頭。你並不總是知道一個對象被釋放在哪個線程上。因此,使用訪問者可能會通過觸發KVO通知而導致問題。

這裏的問題在於,您需要調整dealloc以匹配@property中定義的對象管理策略。例如。不要發佈支持(分配)屬性的iVar。

0

在ARC之前,當你看到新的,alloc,retain和copy時,無論它是一個實例var還是你必須釋放的屬性。在ARC中,只要你有一個強大的變量,你必須將它設置爲零。 無論哪種情況,您都必須重寫dealloc()。