Создайте класс во время выполнения. Почему NSClassFromString И objc_getclass возвращают ноль?
Вопрос
Я пытался использовать оба:
NSClassFromString and objc_getclass
для возврата класса, поэтому я могу создать его во время выполнения, но обе функции возвращают nil для некоторых классов, например " TestClass " ;. Обратите внимание, что NSClassFromString работает для меня для 99% классов.
Если я добавлю
[TestClass class];
прежде чем я вызову NSStringFromClass или objc_getclass, он работает. и если я попытаюсь просто создать класс, используя ссылку на класс, т.е.
[TestClass alloc];
это тоже работает. Так как же заставить класс загружаться во время выполнения, чтобы NSClassFromString или objc_getclass не возвращали nil?
Решение
Я столкнулся с этой же проблемой. В моем случае у меня был код, который искал класс, используя
Class aClass = objc_getClass("Foo");
Это сработало, когда класс Foo находился в том же комплекте проекта, что и мой AppDelegate.
В рамках рефакторинга кода я переместил класс Foo и связанные классы модели из проекта AppDelegate в общий статический проект lib, который было бы проще тестировать и использовать повторно.
Когда я переместил класс Foo в libFooBar, objc_getClass (" Foo ") теперь возвращал nil вместо класса Foo.
Чтобы решить эту проблему, я вызвал интересующий меня класс, чтобы классы из libFooBar были зарегистрированы в среде выполнения Objective-C. Я сделал это так:
Foo* foo = [[Foo alloc] init];
[foo release];
Class aClass = objc_getClass("Foo");
Теперь objc_getClass (" Foo ") снова возвращает класс Foo вместо nil.
Я могу только предположить, что классы статической библиотеки не зарегистрированы, пока не будет сделан вызов одному из классов в статической библиотеке.
Другие советы
Справочник по Objective-C Runtime может помочь вам в этом. Например, документация для objc_getClass гласит: «Объект Class для именованного класса или nil, если класс не зарегистрирован во время выполнения Objective C». & Quot; Оглядываясь на обсуждение регистрации, вы найдете этот кусок в objc_getClassList:
" библиотека времени выполнения Objective C автоматически регистрирует все классы, определенные в вашем исходном коде. Вы можете создавать определения классов во время выполнения и регистрировать их с помощью функции objc_addClass. & Quot;
(И, конечно, документы устарели, потому что objc_addClass устарел, вместо него objc_allocateClassPair и objc_registerClassPair.)
Это похоже на мир боли, если ты не облегчаешь себя. Есть ли шанс, что вы можете просто ссылаться на свои динамические классы в коде при запуске приложения?
Мне пришлось вручную добавить класс (например, TestClass.m) в настройки сборки. Этапы сборки > Компилировать источники > + > TestClass.m