Обработка выхода из приложения в плагине Cocoa, загруженном в приложение Carbon - PullRequest
0 голосов
/ 10 февраля 2010

У меня есть плагин Cocoa, который загружается в существующее приложение Carbon.

Когда плагин загружается впервые, приложение Carbon вызывает функцию инициализации Plugin_Init(), и в этой функции я настраиваю среду следующим образом:

//this is the global autorelease pool
static NSAutoreleasePool* globalPool = nil;

void Plugin_Init()
{
    NSApplicationLoad(); //loads the Cocoa event loop etc
    //create an autorelease pool
    globalPool=[[NSAutoreleasePool alloc] init];

    //callback functions are registered here
    Plugin_defineFunction("doSomething",doSomething,0);
}

Однако приложение Carbon не отправляет никаких уведомлений, когда приложение собирается завершить работу.

Действительно ли необходимо очистить "глобальный" пул авто-релизов, который я создал, когда приложение закрывается?

Я попытался зарегистрироваться для события выхода из приложения Carbon, добавив вызов к функции registerForApplicationQuitNotification() ниже, но когда приложение завершилось, я получил предупреждения о том, что я вызываю -release в недопустимом пуле авто-выпуска. Есть ли проблема с тем, как я справляюсь с событиями Carbon?

//handles the Carbon application quit notification
static pascal OSStatus handleApplicationQuitEvent(EventHandlerCallRef nextHandler, EventRef evt, void *ud)
{
    OSStatus err = noErr;
    UInt32 evtkind;
    evtkind = GetEventKind( evt );
    if ( evtkind == kEventAppQuit ) 
    {
        //release the global autorelease pool
        [globalPool release];
    }
    // call the rest of the handlers
    err = CallNextEventHandler( nextHandler, evt);
    return err;
}

//registers for the Carbon application quit notification
void registerForApplicationQuitNotification()
{
    // install an event handler to tear down some globals on Quit
    static EventHandlerUPP app = NULL;
    EventTypeSpec list[] = {
        {kEventClassApplication, kEventAppQuit},
    };
    app = NewEventHandlerUPP( handleApplicationQuitEvent );
    if (!app)
        return;
    InstallApplicationEventHandler(app, GetEventTypeCount(list), list, NULL, NULL);
}

Ответы [ 2 ]

2 голосов
/ 10 февраля 2010

Вполне вероятно, что NSApplicationLoad настроит первый пул автоматического выпуска NSApplication, который будет ниже вашего в стеке пула автоматического выпуска (так как он был создан первым). В фоновом режиме он истощит этот пул и создаст новый, если это необходимо; в первый раз, когда это происходит, ваш пул исчезает, так как он был выше пула Какао в стеке .

Простое решение - вырезать ваш глобальный пул и позволить NSApplication его создать. Альтернативой может быть создание и слив локальных пулов в каждой функции-обработчике, особенно если вам на самом деле ничего не нужно из Application Kit в вашем плагине.

1 голос
/ 10 февраля 2010

Если пул автоматического выпуска является единственной очисткой, которую вам нужно выполнить, то нет, вам не нужно регистрироваться для уведомления о выходе. Любой созданный вами пул все еще находится в адресном пространстве приложения, которое будет освобождено ОС после завершения процесса.

Кроме того, пулы автоматического выпуска обычно создаются для каждого потока. Если ваши обратные вызовы вызываются в разных потоках, вам может потребоваться создать пул для каждого потока. Обратите внимание, что Cocoa также нужно сказать, что он работает в многопоточной среде; см. раздел «Потоки» в справочнике NSAutoreleasePool .

...