【问题标题】:What is the difference between releasing and autoreleasing?发布和自动发布有什么区别?
【发布时间】:2011-01-05 19:00:58
【问题描述】:
我对释放和自动释放还有一些不清楚的地方。他们两者有什么区别?我有这个代码。用于 facebook 连接。当我去 Facebook 登录时,有时会崩溃,我怀疑可能是因为我没有很好地释放对象。?感谢您的帮助
if (_session.isConnected) {
[_session logout];
} else {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[dialog show];
}
【问题讨论】:
标签:
objective-c
memory-management
autorelease
【解决方案1】:
Memory Management Programming Guide for Cocoa 很快就会成为您最好的朋友。简而言之,Cocoa 中的对象实例是使用引用计数来管理内存的(当然,除非您在 OS X 上使用垃圾收集)。一个对象表明它想要“保留”另一个实例的所有权权益——防止它被释放——通过向它发送-retain 消息。一个对象表示它想通过向另一个实例发送-release 消息来释放该兴趣。如果“保留”的对象数量和对某个对象的所有权兴趣下降到 0(即,当最后一个拥有的实例发送 -release 消息时),保留计数为 0 的实例将被释放。
有时说“我希望这个实例在未来的某个时间发布”很方便。这就是-autorelease 的目的。发送-autorelease 消息会将接收者添加到当前NSAutoreleasePool。当该池耗尽时,它会向池中的所有实例发送-release 消息。 NSAutoreleasePool 会在每个线程的运行循环的每次迭代开始时自动创建,并在迭代结束时耗尽。因此,您可以在方法中执行以下操作:
- (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
}
【解决方案2】:
释放意味着你立即释放它。
自动释放意味着您希望在下一个自动释放池中释放变量。
当您想继续保留变量但又不想造成内存泄漏时,您可以使用自动释放。当您不再需要该变量时,您可以使用 release。
示例:
- (NSNumber *)return5 {
NSNumber * result = [[NSNumber alloc]initWitnInt: 5];
[result autorelease];
return result;
}
为什么我们在那里使用自动释放?
如果我们改用 [result release],变量 result 将在那个时候被销毁。这意味着返回的值将是垃圾。
如果我们根本不释放,变量result 将被永久持有,导致内存泄漏。
我们可以告诉函数的每个调用者释放结果,但这会很头疼并且容易出错。
所以我们使用自动释放。我们标记要在下一个自动释放池中释放的变量。基本上我们在alloc附近标记要释放的变量。因此,口头禅 alloc 与 release 在同一个函数中始终保持配对。
实际上,将所有发布更改为自动发布就可以了。您的内存使用效率不会很高,但是效果很小。所有编程语言中的所有变量都被有效地自动释放。
无论如何,使用 ARC。
【解决方案3】:
背景讨论:
objective-c 是引用计数的,所以当引用计数达到 0 时删除对象。release 立即减少引用计数,autorelease 在 autorelease-pool 弹出时减少它
何时使用:
在分配对象时使用自动释放
- 在当前函数之后不需要它
- 它将被其他一些对象/功能保留,并由保留代码稍后释放
- 当当前函数的逻辑很棘手时,您必须在十几个不同的地方发送释放,然后才能返回
使用“手动”发布
- 恢复以前的保留(如果您正在实施库)
- 如果您需要精确控制释放对象(例如,它们使用大量内存或一段时间内不会弹出自动释放池)
但真的是我的朋友:
埃里克