我刚刚开始使用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操作?
答案 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
}