Работа с плоским пространством имен Objective-C / Какао - PullRequest
2 голосов
/ 05 мая 2010

Я пока не нашел ничего, что решало бы мой конкретный вопрос о пространстве имен.

Я работаю над некоторыми плагинами AudioUnit с графическим интерфейсом на основе Какао. Плагины используют общую библиотеку классов пользовательского интерфейса (ползунки, кнопки и т. Д.), Которые просто добавляются в каждый проект Xcode.

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

Я знаю, что фреймворки - это намеченное решение, но проблемы с издержками и обратной совместимостью не идеальны. Я префикс всех имен классов, где это возможно, но какие параметры я должен обеспечить, чтобы каждый плагин содержал уникальные имена классов для классов общего пользовательского интерфейса?

Обновление:

Решение, к которому я, похоже, пришел, заключается в следующем:

  1. Установить флаг компилятора препроцессора, например OBJC_PREFIX=1.

  2. Создайте файл заголовка, который будет содержать все переопределения имен классов, и условно включите его в заголовок каждого класса, который вы хотите «переименовать», например:

    #ifdef OBJC_PREFIX  
    #include "CocoaPrefixHeader.h"  
    #endif  
    @interface MySlider : ... etc
    
  3. Заполните файл заголовка (в данном случае CocoaPrefixHeader) примерно так:

    #define MySlider Prefix_MySlider  
    #define MyButton Prefix_MyButton  
    
  4. Используя ibtool, преобразуйте все имена ваших классов в существующем файле nib / xib в новые имена, например:

    ibtool --convert MySlider-Prefix_MySlider nibfile.xib --write nibfile2.xib  
    ibtool --convert MyButton-Prefix_MyButton nibfile2.xib --write nibfile2.xib
    

Этот последний шаг преобразует все имена классов, выходы и т. Д. В файл пера. После преобразования вы можете редактировать перо как обычно, а IB отслеживает переопределенные имена.

Этот процесс утомителен и кропотлив, но он работает для меня . Намного лучше обслужить это с самого начала.

Ответы [ 3 ]

2 голосов
/ 06 мая 2010

В файле предварительно скомпилированного заголовка (.pch) для каждого плагина вы можете #define иметь разные имена классов, например ::

#define ClassNameUsedInYourCode ClassNameCompiledInThisProject
#define WidgetButton WahWahPedalPluginWidgetButton

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

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

1 голос
/ 06 мая 2010

У меня была похожая проблема.Мне нужно было, чтобы в одной и той же области приложения одновременно работало несколько версий одного и того же пакета (я даже не помню, почему).Это было нелегко, я обсудил свои проблемы и варианты в списке рассылки Objective-C.В конце я изменил среду сборки так:

  1. Сканирование каждого заголовка на наличие классов, объявленных с @interface.
  2. Создание нового заголовка, заполненного только макросами препроцессора, которые переопределяют имена классовот MyClass до MyClass_v1_00 (или любой другой версии, определенной в файле Info.plist).Этот заголовок назывался ClassRenamer.h.
  3. . В качестве промежуточного этапа сборки проанализируйте все XML-файлы xib и замените ссылки с MyClass на MyClass_v1_00.Это не изменяет исходные файлы xib, что очень удобно.
  4. Измените флаги сборки командной строки, включив ClassRenamer.h для всех .m файлов.

Удивительно, новсе работает отлично, как во время выполнения, так и даже в отладчике.Если я ставлю точку останова на определенную строку, она ломается на любой версии загруженного класса, и Xcode даже показывает имя класса как MyClass_v1_00.Самое большое беспокойство вызывает код, который ищет классы по имени, то есть используя NSClassFromString.

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

Хотя решение, к которому я пришел в обновленной части вопроса, работает как заключительный шаг в проекте, я не могу рекомендовать его ни для чего, когда ваши занятия находятся в состоянии изменения. Мне не удалось добавить дополнительные розетки в классы и показать их в IB, например.

В конце я просто продублировал свои классы и добавил уникальные префиксы имен для разных проектов. Использование ibtool --convert для обновления xib-файла значительно ускорило этот процесс.

Как только все уладится, может быть, идея будет лучше.

...