Как пробиться __NSAutoreleaseNoPool
Я получаю peppered с
*** __NSAutoreleaseNoPool(): Объект 0x1961180 класса NSEvent автореализован без пула на месте - просто утечка
предупреждения во время выполнения и понятия не имеют, в чем причина. Cursory Googles показывают, что это символ, который я могу разбить на Xcode, но добавляя его как символическую точку останова через Run > Manpoint Breakpoints > Add Symbolic Breakpoint или просто через окно управления точками останова, приводит к точке останова с a - рядом с ней вместо проверки, которую я использую для обозначения символа, который не может быть найден.
Я попытался добавить символ "__NSAutoreleaseNoPool" с двумя символами подчеркивания, одним подчеркиванием, и теперь я просто чувствую себя глупо. Ошибки продолжают регистрироваться, а точки останова не попадают. Любые указатели на нарушение символов Obj-C или их отладки будут оценены.
[EDIT: после 10 (еще 10, так что всего несколько десятков, включая, по крайней мере, две перезагрузки Xcode), я получил "Ожидающую точку останова 9". __NSAutoreleaseNoPool "разрешен", напечатанный на моей консоли, и точка останова начала работать. Есть ли способ заставить ожидающую точку останова фактически разрешить?]
Ответы
Ответ 1
Чтобы ответить на ваш вопрос, посмотрите NSDebug.h
. Там вы найдете комментарий, частью которого является:
NAME OF ENV. VARIABLE DEFAULT SET TO...
NSDebugEnabled NO "YES"
NSZombieEnabled NO "YES"
NSDeallocateZombies NO "YES"
NSHangOnUncaughtException NO "YES"
и дальше - эти комментарии:
// Functions used as interesting breakpoints in a debugger
// void __NSAutoreleaseNoPool(void *object);
// Called to log the "Object X of class Y autoreleased with no
// pool in place - just leaking" message. If an environment
// variable named "NSAutoreleaseHaltOnNoPool" is set with string
// value "YES", the function will automatically break in the
// debugger (or terminate the process).
// void __NSAutoreleaseFreedObject(void *freedObject);
// Called when a previously freed object would be released
// by an autorelease pool. If an environment variable named
// "NSAutoreleaseHaltOnFreedObject" is set with string value
// "YES", the function will automatically break in the debugger
// (or terminate the process).
Поэтому вам не нужно устанавливать эти точки останова; просто установите соответствующие переменные среды. Вы можете сделать последнее либо из своего, например, .bashrc
или в Xcode 4 вы можете отредактировать раздел "Запуск" вашей "схемы" и установить их там - то, что я делаю, и оно отлично работает.
Ответ 2
У меня такая же проблема при установке точки останова на __NSAutoreleaseNoPool().
Наконец, я успешно установил команду gdb для использования точки останова.
После запуска отладки нажмите ctrl + C в консоли отладчика.
Используйте "br __NSAutoreleaseNoPool", чтобы установить точку останова и перезапустить отладчик.
Ответ 3
Похоже, вы используете Cocoa в потоке где-то и не обертываете тело потока пулом автозапуска. Вам, вероятно, не нужно использовать точки останова, чтобы найти это. Вы делаете какой-нибудь detachNewThreadSelector?
Ответ 4
Проблема здесь проста: вы выпускаете без пула на месте. Обычно это происходит в инструментах командной строки, написанных против Foundation. Просто добавьте следующий код в свой main()
: (Исключительные части опущены)
int main (…) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/// Your code goes here.
[pool drain]; // This one might not strictly speaking be neccessary.
[pool release];
return 0;
}
Изменить: Если вы не создаете инструмент командной строки, скорее всего, вы делаете что-то непослушное; но тем не менее: если у вас есть код, который вы вызываете перед NSApplicationMain()
, вам нужно обернуть его в тот же базовый код, слив и освободив пул перед вызовом NSApplicationMain
.
Ответ 5
Я знаю, что это старый поток. Просто хотел рассказать немного о правильном решении.
Правильный способ иметь точку останова в _autoreleasenopool - использовать навигатор точки останова в xcode (используйте команду key + 6).
В нижней левой части навигатора точки останова нажмите знак "+" и добавьте символическую брейн-точку. Введите символ как objc_autoreleaseNoPool.