Как пробиться __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.