0

我是 cocoa/xcode 的新手,我正在 Xcode 4.3.2 中编写一个可可应用程序我的目标是 10.5,基础 SDK 是 10.7。我必须支持 10.5 以后的版本。

我使用了手动内存管理,该应用程序在 10.7、10.8 和 10.9 上运行良好。它似乎也适用于 10.6。

在 10.5(我没有系统,但来自报告)

我收到很多这些错误,

Oct 22, 2013 3:44:08 PM: *** _NSAutoreleaseNoPool(): Object 0x1126f49b0 of class NSCFString autoreleased with no pool in place - just leaking
Stack: (0x7fff823a11e8 0x7fff822b9771 0x10002cfb0 0x10002bc19 0x10002add1 0x7fff822bfd35 0x7fff8467ed0f 0x7fff8467ebd1)
Oct 22, 2013 3:44:08 PM: *** _NSAutoreleaseNoPool(): Object 0x1126f4c90 of class NSCFSet     autoreleased with no pool in place - just leaking
Stack: (0x7fff823a11e8 0x7fff822b9771 0x7fff82315748 0x10002bc52 0x10002add1 0x7fff822bfd35 0x7fff8467ed0f 0x7fff8467ebd1)

在我的代码中,我对主线程以外的线程使用了自动释放池

@autoreleasepool
{
  //whatever code calling autorelease on objects..  
}

对于主线程,假设它是自动提供的,我没有提供任何池。我想知道上述错误是否是因为 autoreleasepool 块与 10.5 不兼容?或者我对主线程自动释放池的假设即使对于 10.5 也会自动提供是不正确的?这至少在 10.7 以后是正确的。我不确定 10.5 发生了什么。

任何建议都会很棒..

4

2 回答 2

0

添加一个符号断点(如果您不熟悉如何执行此操作,NSAutoreleaseNoPool()请参阅开发论坛)。当您以这种方式创建对象时,这将使您进入调试器,这将准确告诉您遇到问题的线程。

于 2013-10-23T21:43:25.647 回答
0

@autorelease{}块是 ARC 引入的一项功能,该功能在 10.5 之后。

在 ARC 之前的日子里,你会使用这种结构:

  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  // Code benefitting from a local autorelease pool.

  [pool release];

...这对于所有系统版本上的非 ARC 代码仍然完全有效。

更新

这个答案引起了一些争论(见下文)。当编译器看到一个@autorelease{}块时,它会使用它来生成上述NSAutoreleasePool非块构造,因此应该不存在版本兼容性问题。但是,块本身是仅从 10.6 开始提供的功能。所以 - 尽管关于这一点的文档很薄 - 我相当肯定这是问题的原因。

缺少 10.5 设置,我无法测试。也许其他人可以确认?

更新 2
我似乎大部分都错了(不是第一次!)。

以下是来自 Clang 文档的介绍的一些@autoreleasepool信息:

为了简化自动释放池的使用,并将它们置于编译器的控制之下,Objective-C 中提供了一种新的语句。它写成@autoreleasepool,后跟一个复合语句,即由花括号分隔的新范围。进入此块后,将捕获自动释放池的当前状态。当块正常退出时,无论是通过fallthrough还是定向控制流(如return或break),自动释放池都恢复到保存状态,释放其中的所有对象。当块异常退出时,池不会被耗尽。

@autoreleasepool 可以在非 ARC 翻译单元中使用,具有等效的语义。

尤其是……

如果一个程序引用了 NSAutoreleasePool 类,则该程序是非良构的。

所以我们不应该直接解决 NSAutoreleasePool 自从引入@autorelease{}

由于评论很有启发性,我现在将保留这个错误的答案。

于 2013-10-23T19:28:41.210 回答