带有合成属性的alloc + init - 它会导致保留计数增加2吗?

pat*_*boy 17 iphone memory-management properties objective-c retain

我已经看到了以下代码片段:

在标题中:

SomeClass *bla;
@property(nonatomic,retain) SomeClass *bla;
Run Code Online (Sandbox Code Playgroud)

在实现文件中:

@synthesize bla;
Run Code Online (Sandbox Code Playgroud)

然后

self.bla = [[SomeClass alloc] init];
Run Code Online (Sandbox Code Playgroud)

我认为这项任务将'bla'的保留计数提高了两倍; 一旦通过alloc/init调用,然后通过我们要求通过合成属性设置器发生的保留.

因此,我通常会声明我的属性如下:

在标题中:

SomeClass *_bla; // note the underscore
@property(nonatomic,retain) SomeClass *bla;
Run Code Online (Sandbox Code Playgroud)

在实现文件中:

@synthesize bla = _bla;
Run Code Online (Sandbox Code Playgroud)

然后

_bla = [[SomeClass alloc] init];
Run Code Online (Sandbox Code Playgroud)

如果我最初的假设是正确的 - 我有兴趣听听是否有'正确'的方法来做到这一点,即属性的声明,初始化和内存管理?

Geo*_*che 8

是的,你是对的 - 使用retain属性的合成setter 会增加你已经拥有的实例的ref-count(alloc暗示所有权).

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

_bla = [[SomeClass alloc] init];
Run Code Online (Sandbox Code Playgroud)

...并且记得另外修复保留计数,例如:

self.bla = [[[SomeClass alloc] init] autorelease];
Run Code Online (Sandbox Code Playgroud)


ken*_*ytm 8

我认为这项任务将'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];
}
Run Code Online (Sandbox Code Playgroud)

足够.


有些人可能会用

SomeClass* foo = [[SomeClass alloc] init];
self.bla = foo;
[foo release];
Run Code Online (Sandbox Code Playgroud)

要么

self.bla = [[[SomeClass alloc] init] autorelease];
Run Code Online (Sandbox Code Playgroud)

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

  • 在大多数情况下,你强烈反对的两种模式是完全可以接受和正常的.您链接的答案仅涉及**使用访问器来设置`init`和`dealloc`方法中的对象.在其他任何地方,Apple建议始终使用访问器来访问实例变量. (6认同)