2015-09-12 2 views
2

Я разрабатываю статическую библиотеку, которая распространяется среди других разработчиков. Я хочу использовать класс CocoaLumberjack (DDLog), если он доступен в финальном двоичном файле. В статической библиотеке я определяю интерфейс класса и проверяю [DDLog class], чтобы узнать, существует ли он. Но в хост-приложении, если CocoaLumberjack нет, компоновщик жалуется, потому что DDLog не существует.Избегайте ссылки на символы в статической библиотеке

Я знаю, что я могу отложить проверку символов во время выполнения в конфигурации приложения, но есть ли способ предотвратить компиляцию статической библиотеки от ссылки на класс DDLog в скомпилированных объектах?

+0

Я могу обойти это, используя вместо этого NSInvocation. Но есть ли лучший способ? – Nick

+0

Любая ссылка должна быть разрешена компоновщиком для запуска приложения. Но вы можете использовать слабое соединение: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html. Слабая связь подходит вашей проблеме? – user996142

+0

@ user996142 Я пробовал слабое соединение, см. Мой новый ответ. – Nick

ответ

1

Я не думаю, что при окончательном времени соединения с приложениями возможно иметь неопределенные символы, даже если они слабы. Из документов для Mac OS X л.д.:

При создании выходного файла с статическим редактором связей, когда -twolevel_namespace действует (теперь по умолчанию) все неопределенные ссылки должны быть удовлетворены при статическом время связи. Флагов, которые разрешают неопределенные ссылки, -Usymbol_name, -undefined warning и -undefined sup_press, не могут быть использованы. Если для переменной среды MACOSX_DEPLOYMENT_TARGET установлено значение 10.3, то также можно использовать расширенный dynamic_lookup.

Итак, если есть какие-либо неопределенные ссылки на время ссылки (включая любой используемый вами API, который не находится в текущей версии базового SDK), это приведет к ошибке. Единственный способ обойти это - использовать опцию -undefined dynamic_lookup. К сожалению, это отбрасывает весь поиск символов во время выполнения, вы не можете указать только символы, которые вы хотите пропустить при использовании пространства имен на двух уровнях.

Для меня я не хочу обременять этого разработчика. Поэтому я перешел на использование objc_msgSend и NSClassFromString, избегая при этом использования символа. Жаль, что это должно быть сделано таким образом, и это похоже на то, что Apple может улучшить.