Подтвердить что ты не робот

Класс X реализуется как в Y, так и в Z. Один из двух будет использоваться

У меня есть программа objective-c "tool" (консоль), которая динамически загружает пакет objective-c во время выполнения. Некоторые из файлов пакета разделяют классы из одной и той же структуры, поэтому я получаю сообщение "Класс реализуется в обоих...", которое выгружается на консоль.

Это не мешает чему-либо работать, но наличие сообщений на консоли несколько раздражает. Есть ли способ предотвратить их выброс? Есть ли способ, которым пакет может быть изменен, чтобы они не компилировали/не связывали одни и те же классы?

4b9b3361

Ответ 1

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

  • Создайте предварительную сборку script, которая анализирует все объявления @interface в заголовочных файлах и использует все имена классов. Этот script создает новый заголовок, который содержит примерно следующее:

    #define MyClass        MyClass_Target
    #define MyOtherClass   MyOtherClass_Target
    #define MyThirdClass   MyThirdClass_Target
    

    (очевидно, суффикс _Target задается параметром сборки, который может видеть и использовать pre-build script).

    script может быть Perl или Python script, который просто сканирует каждый *.h файл, извлекающий слово после @interface.

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

  • Если ваши пучки имеют наконечники, это добавляет дополнительный шаг сложности, но это все еще можно сделать. Создайте еще один script, который заменит существующий "компилятор Nib". Эта программа в основном выполняет одно и то же переименование классов, но для nib (это достаточно просто, потому что файлы nib - это XML). Я не могу вспомнить, где его установить, но там есть место в Xcode, которое позволяет вам выбирать, как файлы Nib "скомпилированы". Ваш компилятор nib script в основном представляет собой оболочку, которая переименовывает классы в nib, а затем вызывает реальный компилятор nib (который вы можете узнать, как он вызывается, просматривая журнал сборки).

Работает ли он?

Да, и это работает на удивление хорошо, даже в ситуациях отладки. Когда вы нажимаете точку останова, Xcode отображает имя класса с целевым суффиксом, чтобы вы знали, в каком пакете вы находитесь, несмотря на то, что исходный код показывает что-то другое. "Fix and Continue" все еще работал, насколько я помню.

Кроме того, поскольку переименование класса выполняется непосредственно перед компиляцией, оно не влияет на такие вещи, как управление версиями исходного кода, взаимодействие с Interface Builder и т.д.

Вопросы

  • Динамически сгенерированные имена классов не будут работать, например. Class объекты, возвращенные из NSClassFromString, если только код не был уведомлен о необходимом суффиксе.

  • Такая сложная настройка требует немного обслуживания. Как только я его запустил, он работал хорошо для наших нужд, но время от времени ему нужно было настроить его, чтобы он работал плавно.

Ответ 2

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

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

В частности:

Можно ли изменить пакет, чтобы они не компилировали/не связывали одни и те же классы?

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

Ответ 3

Вы пробовали только добавить заголовки (@interface s) общих классов в пакеты (чтобы компилятор знал об API), но не файлы кода (@implementation s)?

Поскольку вы связываете пакет, компоновщик (ld) не должен жаловаться, что он не может найти реализации данных классов - он делегирует эту задачу динамическому компоновщику (dyld), который пинает когда вы загружаете пакет в свою основную программу. dyld должен затем автоматически установить требуемые ссылки между пучком и программой.

Ответ 4

Если разработчик пакета плагинов вы можете передать - undefined dynamic_lookup в качестве других флагов компоновщика и удалите все библиотеки из плагина, который дублируется в обоих (в основном двоичном и в плагине)