2010-01-16 66 views
11

我对发布和自动释放仍有一些不清楚的理解。他们之间有什么区别?我有这个代码。对于脸书连接。当我登录Facebook时,我有时会崩溃,我怀疑这是因为我没有很好地释放对象。感谢您的任何帮助发布和自动删除有什么区别?

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

回答

20

Memory Management Programming Guide for Cocoa即将成为您最好的朋友。简而言之,Cocoa中的对象实例是使用引用计数管理的内存(当然,除非你在OS X上使用垃圾收集)。一个对象表示它想要在另一个实例中“保留”所有权利益 - 通过发送一个-retain消息来防止它被释放。一个对象表示它想通过发送另一个消息来释放该兴趣。如果对象中拥有“保留”和拥有权感兴趣的对象数量下降到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 

} 
+0

到内存管理编程指南的链接似乎被破坏; iOS版本现在可以在https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html找到。 – CCJ 2014-02-18 18:39:08

3

按照Memory Management Programming Guide for Cocoa

自动释放方法,通过 NSObject的定义,标志着该接收器后 释放。通过自动释放一个 对象 - 即通过发送一个 自动释放消息 - 您声明 您不想拥有超出您发送 autorelease的范围的对象 。

另外:

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

4

背景讨论:

的Objective-C的引用计数,所以对象被删除时参考计数达到0。发布立即减少引用计数,自动释放减少它时,自动释放池弹出

时使用:

使用自动释放分配对象时,如果

  • 你不后需要它目前的功能
  • 它会被某些其他物体/功能重新使用,并且稍后将由保留代码
  • 发布,当前功能的逻辑很棘手时,所以您将不得不发送发布做一回

使用前十几种不同的地方“手动”释放

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

但真的是我freand:

埃里克

7

释放你释放马上手段。 Autoreleasing意味着您希望变量在下一个自动释放池上释放。

当您想保留变量但不想创建内存泄漏时,使用autorelease。当你不再需要这个变量时,你可以使用release。

样品:

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

为什么我们使用自动释放吗?

如果我们使用[result release],那么当时的变量结果将被销毁。这意味着返回的值将是垃圾。

如果我们完全不释放,变量result将被保留FOREVER导致内存泄漏。

我们可以告诉每个调用者该函数释放结果,但这将是一个头痛并容易出错。

所以我们使用autorelease。我们将变量标记在下一个autorelease池中。基本上我们将变量标记在alloc附近。因此,口头分配与同一功能中的释放配对始终保持一致。

其实,你会做很好的改变所有版本autorelease。你的记忆体使用效率不高,但效果很小。所有编程语言中的所有变量都可以有效地自动发布。

无论如何,使用ARC。