分配 +具有合成属性的 init - 是否会导致保留计数增加 2?
我经常看到以下代码片段:
在标头中:
SomeClass *bla;
@property(nonatomic,retain) SomeClass *bla;
在实现文件中:
@synthesize bla;
然后
self.bla = [[SomeClass alloc] init];
我认为此分配将“bla”的保留计数增加了 2;一旦通过 alloc/init 调用,然后通过我们要求通过合成属性设置器发生的保留。
因此,我通常这样声明我的属性:
在标头中:
SomeClass *_bla; // note the underscore
@property(nonatomic,retain) SomeClass *bla;
在实现文件中:
@synthesize bla = _bla;
然后
_bla = [[SomeClass alloc] init];
假设我最初的假设是正确的 - 我有兴趣听听是否有“正确”的方法来做到这一点,即属性的声明、初始化和内存管理?
I've seeen the following snippet quite a bit:
In the header:
SomeClass *bla;
@property(nonatomic,retain) SomeClass *bla;
In the implementation file:
@synthesize bla;
and then
self.bla = [[SomeClass alloc] init];
I think that this assignment puts the retain count for 'bla' up by two; once through the alloc/init call, then through the retain that we asked to happen through the synthesized property setter.
As a result, I normally declare my properties like this:
In the header:
SomeClass *_bla; // note the underscore
@property(nonatomic,retain) SomeClass *bla;
In the implementation file:
@synthesize bla = _bla;
and then
_bla = [[SomeClass alloc] init];
Provided my initial assumption is correct - I'd be interested to hear whether there is 'right' way to do this, i.e. the declaration, initialisation and memory management of properties?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,您是对的 - 使用
retain
属性的综合 setter 会增加您已拥有的实例的引用计数(因为alloc
暗示所有权)。只需使用您在初始化程序中提到的第二种形式:
...并记住修复保留计数,否则,例如:
Yes, you are right - using the synthesized setter of a
retain
property would increase the ref-count on an instance you already own (asalloc
implies ownership).Just go with the second form you mentioned in your initializers:
... and remember to fix the retain count otherwise, e.g.:
真的。
您的最后一段代码是正确的方法,但不建议使用前导下划线。该属性和 ivar 可以共享相同的名称。只
需要就够了。
有些人可能会
使用or
在
-init
方法中 ,但我强烈反对它,因为这会调用不必要的许多方法,并且您无法保证设置器的行为。True.
Your last piece of code is the right way, but the leading underscore is not recommended. The property and the ivar can share the same name. Just
is enough.
Some people may use
or
in the
-init
method, but I strongly discourage it, as this calls unnecessarily many methods, and you cannot guarantee the behavior of the setter.看起来这里的核心问题是对 Cocoa 中对象所有权语义的误解。对于对象上的每个
init
、copy
或retain
调用,都会调用release
或autorelease
代码> 必须制作。这里发生的情况是对init
的调用没有对release
或autorelease
的匹配调用。我认为这里令人困惑的是属性分配的点符号是方法调用的语法糖。所以看起来这只是一个赋值,而实际上它是对属性设置器的调用。
与: 不同,
前者翻译为:
而后者实际上是一项作业。
要解决您的问题,您真正需要做的就是确保调用
init
的代码调用autorelease
,以便保留计数在retain
之后递减。 code> 由 setter 调用。It looks like the core problem here is a misunderstanding of object ownership semantics in Cocoa. For every
init
,copy
orretain
called on an object a call torelease
orautorelease
must be made. What's happening here is that the call toinit
doesn't have a matching call torelease
orautorelease
.I think what's confusing here is that the dot-notation for property assignment is syntactic sugar for a method call. So it looks like it's just an assignment when in actuality it's a call to a property setter.
is not the same thing as:
The former translates into:
while the latter is literally an assignment.
To fix your issue all you really need to do is ensure that the code that calls
init
callsautorelease
so that the retain count will be decremented after theretain
call by the setter.不存在重复计算。由 Synthesize 创建的 setter 在执行保留之前执行释放。请参阅 Apple 网站上引用的斯坦福大学关于 Objective C Class 3 的课程。还值得注意的是,对于 iboutlets,不需要 alloc init,因为它是通过加载 xib 文件来执行的
There is no double count. The setter created by by synthesize does a release before doing a retain. See Stanford class on objective c class 3 as referenced on the apple website. It is also worth noting that in case of iboutlets the alloc init is not needed as it is performed through loading of the xib file