[英]alloc + init with synthesized property - does it cause retain count to increase by two?
我已經看到了以下代碼片段:
在標題中:
SomeClass *bla;
@property(nonatomic,retain) SomeClass *bla;
在實現文件中:
@synthesize bla;
然后
self.bla = [[SomeClass alloc] init];
我認為這項任務將'bla'的保留計數提高了兩倍; 一旦通過alloc / init調用,然后通過我們要求通過合成屬性設置器發生的保留。
因此,我通常會聲明我的屬性如下:
在標題中:
SomeClass *_bla; // note the underscore
@property(nonatomic,retain) SomeClass *bla;
在實現文件中:
@synthesize bla = _bla;
然后
_bla = [[SomeClass alloc] init];
如果我最初的假設是正確的 - 我有興趣聽聽是否有'正確'的方法來做到這一點,即屬性的聲明,初始化和內存管理?
是的,你是對的 - 使用retain
屬性的合成setter會增加你已經擁有的實例的ref-count(因為alloc
意味着所有權)。
只需使用初始化程序中提到的第二種形式:
_bla = [[SomeClass alloc] init];
...並且記得另外修復保留計數,例如:
self.bla = [[[SomeClass alloc] init] autorelease];
我認為這項任務將'bla'的保留計數提高了兩倍;
真正。
我很想知道是否有'正確'的方法來做到這一點
您的最后一段代碼是正確的方式,但不建議使用前導下划線。 該物業和ivar可以共享相同的名稱。 只是
@interface Foo : Bar {
SomeClass* bla;
}
@property (nonatomic, retain) SomeClass* bla;
@end
@implementation Foo
@synthesize bla;
-(id)init {
...
bla = [[SomeClass alloc] init];
...
}
-(void)dealloc {
[bla release];
...
[super dealloc];
}
足夠。
有些人可能會用
SomeClass* foo = [[SomeClass alloc] init];
self.bla = foo;
[foo release];
要么
self.bla = [[[SomeClass alloc] init] autorelease];
在-init
方法中,但我強烈反對它,因為這會不必要地調用許多方法, 並且您無法保證setter的行為 。
看起來這里的核心問題是對Cocoa中對象所有權語義的誤解。 對於在對象上調用的每個init
, copy
或retain
,必須調用release
或autorelease
。 這里發生的事情是對init
的調用沒有匹配的release
或autorelease
調用。
我認為這里令人困惑的是,屬性賦值的點符號是方法調用的語法糖。 所以看起來它只是一個賦值,實際上它是對屬性setter的調用。
self.bla = [[SomeClass alloc] init];
與以下內容不同:
bla = [[SomeClass alloc] init];
前者轉化為:
[self setBla: [[SomeClass] alloc] init]];
而后者實際上是一項任務。
要解決您的問題,您真正需要做的是確保調用init
的代碼調用autorelease
以便在setter的retain
調用之后保留計數將減少。
沒有重復計算。 由synthesize創建的setter在執行保留之前執行釋放。 請參閱蘋果網站上引用的目標c類3的斯坦福大學課程。 值得注意的是,在iboutlet的情況下,不需要alloc init,因為它是通過加載xib文件來執行的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.