分配 +具有合成属性的 init - 是否会导致保留计数增加 2?

发布于 2024-09-10 07:11:54 字数 673 浏览 5 评论 0原文

我经常看到以下代码片段:

在标头中:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不及他 2024-09-17 07:11:54

是的,您是对的 - 使用 retain 属性的综合 setter 会增加您已拥有的实例的引用计数(因为 alloc 暗示所有权)。

只需使用您在初始化程序中提到的第二种形式:

_bla = [[SomeClass alloc] init];

...并记住修复保留计数,否则,例如:

self.bla = [[[SomeClass alloc] init] autorelease];

Yes, you are right - using the synthesized setter of a retain property would increase the ref-count on an instance you already own (as alloc implies ownership).

Just go with the second form you mentioned in your initializers:

_bla = [[SomeClass alloc] init];

... and remember to fix the retain count otherwise, e.g.:

self.bla = [[[SomeClass alloc] init] autorelease];
对你的占有欲 2024-09-17 07:11:54

我认为这个分配使“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];

使用or

self.bla = [[[SomeClass alloc] init] autorelease];

-init 方法中 ,但我强烈反对它,因为这会调用不必要的许多方法,并且您无法保证设置器的行为

I think that this assignment puts the retain count for 'bla' up by two;

True.

I'd be interested to hear whether there is 'right' way to do this

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

@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];
}

is enough.


Some people may use

SomeClass* foo = [[SomeClass alloc] init];
self.bla = foo;
[foo release];

or

self.bla = [[[SomeClass alloc] init] autorelease];

in the -init method, but I strongly discourage it, as this calls unnecessarily many methods, and you cannot guarantee the behavior of the setter.

七度光 2024-09-17 07:11:54

看起来这里的核心问题是对 Cocoa 中对象所有权语义的误解。对于对象上的每个 initcopyretain 调用,都会调用 releaseautorelease代码> 必须制作。这里发生的情况是对 init 的调用没有对 releaseautorelease 的匹配调用。

我认为这里令人困惑的是属性分配的点符号是方法调用的语法糖。所以看起来这只是一个赋值,而实际上它是对属性设置器的调用。

self.bla = [[SomeClass alloc] init];

与: 不同,

bla = [[SomeClass alloc] init];

前者翻译为:

[self setBla: [[SomeClass] alloc] init]];

而后者实际上是一项作业。

要解决您的问题,您真正需要做的就是确保调用 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 or retain called on an object a call to release or autorelease must be made. What's happening here is that the call to init doesn't have a matching call to release or autorelease.

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.

self.bla = [[SomeClass alloc] init];

is not the same thing as:

bla = [[SomeClass alloc] init];

The former translates into:

[self setBla: [[SomeClass] alloc] init]];

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 calls autorelease so that the retain count will be decremented after the retain call by the setter.

水晶透心 2024-09-17 07:11:54

不存在重复计算。由 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文