0

我有一个加载到现有 Carbon 应用程序中的 Cocoa 插件。

首次加载插件时,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);
}
4

2 回答 2

2

很可能NSApplicationLoad设置了 NSApplication 的第一个自动释放池,它将在自动释放池堆栈中低于您的自动释放池(因为它是首先创建的)。在后台,它将耗尽该池并根据需要创建一个新池;第一次发生这种情况时,您的池消失了,因为它在堆栈中位于 Cocoa 的池之上

简单的解决方案是删除您的全局池并让 NSApplication 创建它。另一种方法是在每个处理程序函数中创建和排出本地池,特别是如果您实际上不需要插件中的应用程序工具包中的任何内容。

于 2010-02-10T10:01:09.450 回答
1

如果自动释放池是您需要做的唯一清理,那么不,您不需要注册退出通知。您创建的任何池仍在应用程序的地址空间内,当进程终止时,操作系统将释放该地址空间。

此外,自动释放池通常是按线程创建的。如果您的回调在不同的线程上调用,您可能需要为每个线程创建一个池。请注意,还需要告知 Cocoa 它在多线程环境中运行;请参阅NSAutoreleasePool 参考的线程部分。

于 2010-02-10T07:49:18.450 回答