objective-c - Core MIDI 回调中未注册线程上的 GC

标签 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 操作?

最佳答案

因为垃圾收集器不知道您在此线程上没有使用 Cocoa。

Cocoa 提供的垃圾收集器是一个保守的垃圾收集器:它实际上对程序的结构几乎一无所知。它所做的只是扫描每个线程的堆栈和堆上的对象,寻找看起来指针的位模式,如果在这个可能的位置有一个对象,它就会使其保持事件状态。

显然,存在误报的可能性。您可以拥有一个具有类似于指针的值的整数,并且垃圾收集器会认为它是一个。

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

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

关于objective-c - Core MIDI 回调中未注册线程上的 GC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3648605/

相关文章:

macos - chmod 无法更改权限

ios - 如何减少我的应用程序的 ipa 大小

objective-c - (Cocoa Mac) NSWindowController showWindow 分配/初始化一个新的 NSWindowController?

html - 如何在 UIWebView 中显示 HTML 代码?

objective-c - 获取 NSImage 的正确图像宽度和高度

xcode - 强制 Xcode 更新项目文件

Java插件开发调试接口(interface)问题

带有 AFNetworking 的 iOS POST 请求

objective-c - NSWindow 模态问题

Mavericks 上的 MySQL 服务器启动问题