GC на незарегистрированном потоке в обратном вызове Core MIDI - PullRequest
0 голосов
/ 06 сентября 2010

Я только начинаю снова с разработки для Mac.

Я использую CoreMIDI, который является C API, который позволяет мне определять функцию обратного вызова C, которая будет вызываться с сервера MIDI в отдельном потоке всякий раз, когдаMIDI сообщение приходит.Регистрация этого обратного вызова выполняется в коде Objective-C / C, инициированном вызовом awakeFromNib.

Кажется, что он работает нормально, за исключением того, что когда я получаю свой первый обратный вызов, я получаю следующее предупреждение на консоли:

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, но я думал, что это только для частей Какао.И мой обратный вызов не использует никакого кода Какао, это просто бесплатная функция, которая использует некоторые функции CoreMIDI и CoreFoundation (включая CFSTR, если это имеет значение).Почему операция GC происходит в этом потоке, если я не использую какие-либо объекты Какао?

Ответы [ 2 ]

1 голос
/ 06 сентября 2010

Поскольку сборщик мусора не знает, что вы не используете Какао в этом потоке.

Сборщик мусора, который использует Cocoa, является консервативным сборщиком мусора: он фактически почти ничего не знает о том, как работает ваша программа.структурированный.Все, что он делает, это сканирует стек каждого потока и объекты в куче на предмет битовых комбинаций, которые выглядят как указатели, и если в этом потенциальном месте есть объект, он поддерживает его.

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

Кроме того, вы можете выделять сборочную память как malloc, как NSAllocateCollectable.GC также должен учитывать их, тем более что возвращаемый указатель может быть передан в код C, который даже не знает о сборке мусора.

EDIT Помимо NSAllocateCollectable, объекты Core Foundation(CF -префиксированные типы) можно сделать сборщиком мусора с помощью CFMakeCollectable.Как только он будет использован, сборщик мусора позаботится о них.

0 голосов
/ 14 мая 2012

Если вы создаете 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
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...