所以我正在调试一个应用程序,因为它的应用程序已经发布了,我为“所有异常”启用了一个通用断点。从那时起,每次运行应用程序时,控制台都会打印:
Catchpoint 2(throw)待定断点1 - “objc_exception_throw”已解决
objc [11765]:类__NSCFLocale的对象0x8f18ff0自动释放,没有池到位 - 只是泄漏 - 在objc_autoreleaseNoPool()上中断调试
objc [11765]:类__NSCFNumber的对象0x8f190a0自动释放,没有池到位 - 只是泄漏 - 在objc_autoreleaseNoPool()上中断以进行调试
objc [11765]:类__NSCFLocale的对象0x8f1fef0自动释放,没有池到位 - 只是泄漏 - 在objc_autoreleaseNoPool()上中断以进行调试
字面打印3次。我不知道这意味着什么,但看起来很糟糕。任何建议将不胜感激。
答案 0 :(得分:35)
新信息
我通过创建一个混合自动释放方法确定了我的问题所在。
除非你知道自己在做什么,否则我不建议这样做,但这是我发现的。
+ (void) load; //Method is called outside the original autorelease pool.
+ (void) initialize; // Method is called outside the original autorelease pool.
NSThread创建自己的线程,被调用的方法应该包装在自动释放池中。
Grand Central Dispatch在使用“dispatch _...”命令时负责调整自动释放池。但是,当您手动调度时。您可能希望将其包装在自动释放池中。
此外,ARC不会让您知道在池外发生自动释放。
因此,如果您使用ARC并且知道您将在自动释放池之外。你无能为力。你会想要避免所有方便的方法。
使用它。
[[NSString alloc] initWithFormat:@"%@",myObject];
而不是
[NSString stringWithFormat:@"%@",myObject];
这将允许弧系统保留和释放,但是方便方法完成的基础自动释放将被跳过,因为您将不会使用方便方法。
希望有所帮助。
原始答案
好的,我觉得这个问题没有得到足够详细的回答。
正在呈现的消息是
objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
调试器指出一个可能的断点,它将帮助您调试情况。现在虽然这个断点确实没有帮助调试情况。我认为重要的是知道如何将该断点添加到调试器中,因此我花时间修补它(在搜索互联网并找不到任何内容之后),直到我得到它来打破该错误。
有点烦人的是,所有错误的中断都没有捕获到这一点,但这里是将断点添加到调试器的步骤。
您要做的第一件事是选择调试器的断点导航器
点击此标签
接下来,您将看向导航器窗格的底部,然后按加号按钮
这将允许您手动添加断点。
我选择了一个C ++断点,并在名称文本字段中输入了消息名称。
添加此异常之后确实会中断。
然而,作为客观的开发人员,这可能对您有用,也可能没有用。这突破了汇编代码。
不幸的是,它只在线程的调用堆栈上显示了这一点。
事实证明,autorelease问题是因为在dispatch_once调用中调用了autorelease。进一步调查显示+(空)负荷;在其他任何事情之前调用类的方法。这是通过call_load_methods函数完成的,并且位于main方法的线程之外。
要纠正这个问题,我只是在调用周围添加了自动释放池包装器。
另一种解决方案可能是在+(void)加载中添加自动释放池;方法。但这足以满足我的用途。
注意:我将此添加到此处的帖子中,因为我不喜欢找到问题并且无法找出所得答案的所有路径。如果调试器告诉您向列出的函数添加断点,那么应该在某处获取某些信息以获取该信息。希望这会降低一些试图找到这个答案的人的挫败感。
答案 1 :(得分:1)
cocoa api中的许多方法都返回自动释放的对象。特别是那些返回不以init
开头的对象的方法,例如[NSNumber numberWithLong:]
。如果您没有自动释放池,那么这些对象将被泄露。您可以在documentation中找到有关使用NSAutoreleasePool
的更多信息。
答案 2 :(得分:1)
这意味着您需要在发生的线程上创建自动释放池。否则,您的分配对象将不会被销毁(如消息所示)。因此,在符号处中断/暂停,然后将堆栈向上移动到您的线程(或程序)条目并添加自动释放池。就是这样。