GC在核心MIDI回调中的未注册线程上

时间:2010-09-06 01:49:04

标签: objective-c cocoa macos

我刚刚开始使用Mac开发。

我正在使用CoreMIDI这是一个C API,它允许我定义一个C回调函数,当MIDI消息到达时,它将在一个单独的线程上从MIDI服务器调用。此回调的注册是在awakeFromNib调用触发的Objective-C / C代码中完成的。

它似乎工作正常,除非我收到第一个回调,我在控制台上收到以下警告消息:

MidiList(6685,0x103ddb000) malloc: *** auto malloc[6685]: error: GC operation on unregistered thread. Thread registered implicitly. Break on auto_zone_thread_registration_error() to debug.

我在网上看了这个,听起来像是一个无害的错误。但对我来说奇怪的是我不明白“GC操作”是如何发生的?我的项目确实启用了GC,但我认为这只适用于Cocoa部分。我的回调函数不使用任何Cocoa代码,它只是一个使用一些CoreMIDI和CoreFoundation功能的自由函数(如果重要的话包括CFSTR)。如果我没有使用任何Cocoa对象,为什么在该线程上会发生GC操作?

2 个答案:

答案 0 :(得分:1)

因为垃圾收集器不知道你在这个帖子上没有使用Cocoa。

Cocoa sports的垃圾收集器是一个保守的垃圾收集器:它实际上几乎不了解程序的结构。所有这一切都是扫描每个线程的堆栈和堆上的对象,以查找看起来像指针的位模式,如果在这个可能的位置有一个对象,它会使它保持活动状态。< / p> 显然,有可能出现误报。你可以有一个整数,其值看起来像指针,垃圾收集器会认为它是一个。

此外,您可以malloc方式使用NSAllocateCollectable分配垃圾收集内存。 GC也必须考虑它们,特别是因为返回的指针可以传递给甚至不知道垃圾收集的C代码。

编辑除了NSAllocateCollectable之外,可以在CFMakeCollectable的帮助下对Core Foundation对象(CF - 前缀类型)进行垃圾回收。一旦它被使用,垃圾收集器将负责它们。

答案 1 :(得分:0)

如果您要创建pthread,请将此objc_registerThreadWithCollector();添加到您的pthread。

如果您找不到符号或链接错误,请使用以下代码

 #include <dlfcn.h>
    void (*registerThreadWithCollector_fn)(void);
    registerThreadWithCollector_fn = (void(*)(void)) dlsym(RTLD_NEXT, "objc_registerThreadWithCollector");
    if (registerThreadWithCollector_fn) {
        (*registerThreadWithCollector_fn)();
    } else {
        // do something else
    }