Objective-C(iPhone)ivars和内存管理

Jas*_*ary 3 iphone objective-c

我是NSURLConnection的子类,并使用MGTwitterEngine作为基础来帮助我开始.这可能是无关紧要的.但是,我注意到他们的代码中没有使用@property@synthesize用于他们的ivars.他们将ivars包装在accessor方法中,如下所示:

- (NSString *)identifier {
  return [[_identifier retain] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

我的问题是两部分.首先,什么效果也retain随后autorelease有哪些?在我看来它会取消自己,或者更糟糕但是泄漏.

其次,如果我要更改头文件:

@property (nonatomic, retain, readonly) NSString* _identifier;
Run Code Online (Sandbox Code Playgroud)

并使用@synthesize indentifier = _identifier,这不会与访问方法做同样的事情,而不必写它?

也许只是两种不同的方式来做同样的事情.但我想确保我有正确的理解.谢谢.

Pey*_*loW 8

使用@synthesize实际上只会创建一个setter和一个getter方法.为您自动生成的代码保证使用适当的内存管理,因此您无需担心.

MGTwitterEngines的使用return [[ivar retain] autorelease实际上是正确的方法.让我们举两个例子.

假设getter定义为:

-(Foo)foo {
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

然后我们执行这段代码:

  1. bar = [[bar alloc] init]; // bar的计数为1.
  2. foo = bar.foo; // foo保留计数为1(由bar拥有).
  3. [bar release]; //酒吧和所有它的ivars都是imidiatetly释放!
  4. [foo doSomething]; //自上一行发布foo以来,这将崩溃.

如果我们改为将getter更改为:

-(Foo)foo {
    return [[foo retain] autorelease];
}
Run Code Online (Sandbox Code Playgroud)
  1. bar = [[bar alloc] init]; // bar的保留计数为1
  2. foo = bar.foo; // foo的保留计数为2(一个由bar拥有,一个由autorelease pool拥有).
  3. [bar release]; //酒吧和所有它的ivars都是imidiatetly释放!
  4. [foo doSomething]; //不会崩溃因为foo仍然存在且由autorelease pool拥有.

希望这能解释为什么你应该总是从你所有的getter中正确地返回自动释放的对象.重要的是,任何返回值都可以在其父级的解除分配后继续存在,因为没有类可以保证客户端一旦暴露在野外就会对其值进行处理.