11

我仍然对发布和自动发布有一些不清楚的了解。他们两者有什么区别?我有这个代码。用于 facebook 连接。当我登录 Facebook 时有时会崩溃,我怀疑可能是因为我没有很好地释放对象。?感谢您的帮助

if (_session.isConnected) {
        [_session logout];
    } else {
        FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
        [dialog show];
    }
4

4 回答 4

22

Cocoa 内存管理编程指南很快就会成为你最好的朋友。简而言之,Cocoa 中的对象实例是使用引用计数来管理内存的(当然,除非您在 OS X 上使用垃圾收集)。一个对象表明它想要“保留”另一个实例的所有权权益——防止它被释放——通过向它发送-retain消息。一个对象表明它想通过向另一个实例发送-release消息来释放这种兴趣。如果“保留”的对象数量和对某个对象的所有权兴趣下降到 0(即,当最后一个拥有的实例发送-release消息时),则保留计数为 0 的实例将被释放。

有时说“我希望这个实例在未来某个时间发布”很方便。这就是-autorelease. 发送-autorelease消息会将接收者添加到当前的NSAutoreleasePool. 当该池耗尽时,它会向池中的-release所有实例发送一条消息。AnNSAutoreleasePool在每个线程的运行循环的每次迭代开始时自动创建,并在该迭代结束时排出。因此,您可以在方法中执行以下操作:

- (id)myMethod {
  return [[[MyObject alloc] init] autorelease];
}

此方法的调用者将取回一个实例,-retain如果他们希望保留该实例。如果他们不保留它,它至少会一直存在,直到封闭的自动释放池被耗尽:

- (void)someOtherMethod {
...

id instance = [obj myMethod];
... // do more with instance, knowing that it won't be dealloc'd until after someOtherMethod returns

}
于 2010-01-16T06:34:15.067 回答
11

释放意味着你立即释放它。自动释放意味着您希望在下一个自动释放池中释放变量。

当您想继续保留变量但又不想造成内存泄漏时,您可以使用自动释放。当您不再需要该变量时,您可以使用 release。

样本:

- (NSNumber *)return5 {
    NSNumber * result = [[NSNumber alloc]initWitnInt: 5];
    [result autorelease];
    return result;
}

为什么我们在那里使用自动释放?

如果我们改用 [result release],变量 result 将在那个时候被销毁。这意味着返回的值将是垃圾。

如果我们根本不释放,变量result将永远持有,从而导致内存泄漏。

我们可以告诉函数的每个调用者释放结果,但这会让人头疼并且容易出错。

所以我们使用自动释放。我们标记要在下一个自动释放池中释放的变量。基本上我们在alloc附近标记要释放的变量。因此,咒语 alloc 与 release 在同一个函数中始终保持配对。

实际上,将所有发布更改为自动发布就可以了。您的内存使用效率不会很高,但是效果很小。所有编程语言中的所有变量都有效地自动释放。

无论如何,使用ARC。

于 2012-09-21T03:47:54.190 回答
4

背景讨论:

Objective-c 是引用计数的,所以当引用计数达到 0 时,对象会被删除。release 立即减少引用计数,autorelease 会在 autorelease-pool 弹出时减少它

何时使用:

分配对象时使用自动释放 if

  • 在当前函数之后你不需要它
  • 它将被其他一些对象/功能保留,稍后将由保留代码释放
  • 当当前函数的逻辑很棘手时,因此您必须在十几个不同的地方发送 release 才能返回

使用“手动”发布

  • 恢复以前的保留(如果您正在实施库)
  • 如果您需要精确控制释放对象(例如,它们使用大量内存,或者一段时间内不会弹出自动释放池)

但真的是我的朋友:

埃里克

于 2010-01-16T07:01:06.750 回答
3

根据Cocoa 的内存管理编程指南

由 NSObject 定义的 autorelease 方法将接收者标记为稍后发布。通过自动释放一个对象——也就是说,通过向它发送一个自动释放消息——你声明你不想拥有超出你发送自动释放的范围的对象。

还:

因此,自动释放方法允许每个对象使用其他对象,而不必担心它们的处置。

于 2010-01-16T06:24:38.633 回答