xcode 断点指出“objc_autoreleaseNoPool”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10003962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 23:52:29  来源:igfitidea点击:

Breakpoint pointing out "objc_autoreleaseNoPool"

objective-ciosxcodebreakpoints

提问by Andrew

So I'm debugging an app in preperation for its app so release, and I enabled a universal breakpoint for "All Exceptions". Since then, everytime I run the app, the console prints:

所以我正在调试一个应用程序,为其应用程序的发布做准备,并且我为“所有异常”启用了一个通用断点。从那以后,每次运行应用程序时,控制台都会打印:

Catchpoint 2 (throw)Pending breakpoint 1 - "objc_exception_throw" resolved

objc[11765]: Object 0x8f18ff0 of class __NSCFLocale autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

objc[11765]: Object 0x8f190a0 of class __NSCFNumber autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

objc[11765]: Object 0x8f1fef0 of class __NSCFLocale autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

Catchpoint 2 (throw)Pending 断点 1 - "objc_exception_throw" 已解决

objc[11765]: __NSCFLocale 类的对象 0x8f18ff0 自动释放,没有池 - 只是泄漏 - 中断 objc_autoreleaseNoPool() 进行调试

objc[11765]: __NSCFNumber 类的对象 0x8f190a0 自动释放,没有池 - 只是泄漏 - 中断 objc_autoreleaseNoPool() 进行调试

objc[11765]: __NSCFLocale 类的对象 0x8f1fef0 自动释放,没有池 - 只是泄漏 - 中断 objc_autoreleaseNoPool() 进行调试

Literally printed 3 times. I have no idea what this means but it looks bad. Any advice would be appreciated.

字面上印了3次。我不知道这意味着什么,但看起来很糟糕。任何意见,将不胜感激。

回答by The Lazy Coder

New Info

新信息

I determined where my issue lies by creating a swizzled autorelease method.

我通过创建一个混合的自动释放方法来确定我的问题所在。

I dont recommend doing that unless you know what you are doing, however this is what I found out.

我不建议这样做,除非您知道自己在做什么,但这是我发现的。

+ (void) load; //Method is called outside the original autorelease pool.
+ (void) initialize; // Method is called outside the original autorelease pool.

NSThread creates its own thread, the called method should be wrapped in an autorelease pool.

NSThread 创建自己的线程,被调用的方法应该被包装在一个自动释放池中。

Grand Central Dispatch takes care of adapting over the autorelease pool when using the "dispatch_..." commands. however, when you dispatch manually. you may want to wrap it in an autorelease pool.

使用“dispatch_...”命令时,Grand Central Dispatch 负责调整自动释放池。但是,当您手动调度时。您可能希望将其包装在自动释放池中。

Also, ARC does not handle letting you know that an autorelease will happen outside a pool.

此外,ARC 不处理让您知道自动释放将在池外发生。

Therefore if you are using ARC and know that you will be outside the autorelease pool. And there is nothing you can do about that. You will want to avoid all convenience methods.

因此,如果您正在使用 ARC 并且知道您将在自动释放池之外。你对此无能为力。您将希望避免所有方便的方法。

use this.

用这个。

[[NSString alloc] initWithFormat:@"%@",myObject];

instead of this

而不是这个

[NSString stringWithFormat:@"%@",myObject];

this will allow the arc system to retain and release, but the underlying autorelease done by the convenience method will be skipped as you will not have used the convenience method.

这将允许 arc 系统保留和释放,但将跳过由便捷方法完成的底层自动释放,因为您不会使用便捷方法。

Hope that helps.

希望有帮助。

Original Answer

原答案

Ok, I dont feel this question was answered with enough detail.

好吧,我觉得这个问题的回答不够详细。

the message being presented was

所呈现的消息是

objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

The debugger is pointing out a possible breakpoint that will help you debug the situation. Now while this breakpoint really did little to help debug the situation. I think that it is important to know how to add that breakpoint to the debugger and so I spent the time tinkering with it (after scouring the internet and finding nothing) until I got it to break on that error.

调试器指出了一个可能的断点,它将帮助您调试这种情况。现在,虽然这个断点对调试情况几乎没有帮助。我认为知道如何将断点添加到调试器很重要,所以我花时间修补它(在搜索互联网并没有找到任何东西之后),直到我让它因该错误而中断。

It is kind of annoying that break on all errors does not catch this, but here are the steps to add the breakpoint to the debugger.

有点烦人的是,中断所有错误并没有捕捉到这一点,但这里是将断点添加到调试器的步骤。

first thing you want to do is select the debugger's breakpoint navigator

您要做的第一件事是选择调试器的断点导航器

navigator toolbar

导航工具栏

by clicking on this tab

通过单击此选项卡

breakpoint button

断点按钮

next you look toward the bottom of the navigator pane and press the Plus button

接下来,您看向导航器窗格的底部,然后按加号按钮

Add Exception Breakpoint

添加异常断点

This will allow you to manually add a breakpoint.

这将允许您手动添加断点。

I selected a C++ breakpoint and entered the message name into the name text field.

我选择了一个 C++ 断点并将消息名称输入到名称文本字段中。

Adding custom C++ exception

添加自定义 C++ 异常

after adding this exception it did in fact break.

添加此异常后,它确实中断了。

However this may or may not be useful to you as an objective c developer. This broke into the Assembly code.

但是,作为客观的 c 开发人员,这可能对您有用,也可能没有用。这闯入了汇编代码。

assembly code at achieved breakpoint.

达到断点处的汇编代码。

Unfortunately it only showed this point on the call stack for the thread.

不幸的是,它只在线程的调用堆栈上显示了这一点。

Thread list

主题列表

And it turned out that the autorelease problem was because a class called autorelease in a dispatch_once call. and further investigation revealed that the +(void)load; method on the class was called before anything else. this is done via the call_load_methods function and is outside the thread on the main method.

事实证明,自动释放问题是因为在 dispatch_once 调用中调用了一个名为 autorelease 的类。进一步调查显示+(void)load; 类上的方法在其他任何事情之前被调用。这是通过 call_load_methods 函数完成的,并且在 main 方法的线程之外。

Error Call and Stack

错误调用和堆栈

to correct this, I merely added the autorelease pool wrapper around the call.

为了纠正这个问题,我只是在调用周围添加了自动释放池包装器。

updated error call

更新错误调用

another solution may be to add the autorelease pool inside the +(void)load; method. but this was sufficient for my uses.

另一种解决方案可能是在 +(void)load 中添加自动释放池;方法。但这对我的用途来说已经足够了。

NOTE: I am adding this to the post here because I do not like finding an issue and not being able to figure out all paths to the resulting answer. If the debugger tells you to add a breakpoint to the function listed, then there should be some information somewhere to get that information. Hopefully this will lower the frustration of some of those out there trying to find this answer.

注意:我将此添加到此处的帖子中,因为我不喜欢发现问题并且无法找出结果答案的所有路径。如果调试器告诉您向列出的函数添加断点,那么应该在某处有一些信息可以获取该信息。希望这会降低一些试图找到这个答案的人的挫败感。

回答by highlycaffeinated

Many of the methods in the cocoa api return autoreleased objects. In particular, those methods that return an object that don't begin with init, such as [NSNumber numberWithLong:]. If you don't have an autorelease pool in place, those objects will be leaked. You can find more information on using NSAutoreleasePoolin the documentation.

cocoa api 中的许多方法都返回自动释放的对象。特别是那些返回不以 开头的对象的方法init,例如[NSNumber numberWithLong:]. 如果您没有适当的自动释放池,这些对象将被泄漏。您可以NSAutoreleasePool文档中找到有关使用的更多信息。

回答by justin

It means you need to create an autorelease pool on the thread it happens. Otherwise, your allocated objects will not be destroyed (as suggested by the message). So, break/pause at the symbol, then walk up the stack to your thread (or program) entry and add an autorelease pool. That's all.

这意味着您需要在它发生的线程上创建一个自动释放池。否则,您分配的对象将不会被销毁(如消息所建议的那样)。因此,在符号处中断/暂停,然后将堆栈向上移动到您的线程(或程序)条目并添加一个自动释放池。就这样。