簡體   English   中英

帶有合成屬性的alloc + init - 它會導致保留計數增加2嗎?

[英]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中對象所有權語義的誤解。 對於在對象上調用的每個initcopyretain ,必須調用releaseautorelease 這里發生的事情是對init的調用沒有匹配的releaseautorelease調用。

我認為這里令人困惑的是,屬性賦值的點符號是方法調用的語法糖。 所以看起來它只是一個賦值,實際上它是對屬性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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM