2013-07-18 3 views
1

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

CGFloat DegreesToRadians(CGFloat degrees); 
UIColor RGB(int r, int g, int b); 

Это все хорошо ОДНАКО, когда кто-то добавляет мою библиотеку к их проекту, если они тоже определили DegreesToRadians или RGB функцию, или они используя другую библиотеку, которая их определяет, тогда будет ошибка компиляции Redfinition of DegreesToRadians.

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

ПРЕДОСТЕРЕЖЕНИЯ:

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

  • Я знаю, что могу определить функции «статические» и «с» в классе (классах), которые их используют, но эти функции используются во многих классах, и поэтому этот подход нарушит принцип СУХОЙ.

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

+1

Вы хотите, чтобы эти функции использовались другими? – Horst

+0

Идеально да, но только если им нужно (т. Е. Они могут вручную импортировать). Однако меня все равно интересовали решения, которые не позволяют использовать функции. –

ответ

3

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

Добавьте .h, где они определены в разделе «частные заголовки» в конфигурации библиотеки. Тогда они не будут видны пользователям, использующим вашу библиотеку.

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

MyConverter 
- (CGFloat)radiansFromDegrees:(CGFloat)degrees; 

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

+0

Частная часть заголовка звучит разумно, но что происходит, если пользователь библиотеки имеет функции с одной и той же сигнатурой в своем коде? Разве это не приведет к дублированию символьной ошибки при связывании? –

+0

Причина, по которой я не использую методы, заключается в том, что они используются тысячи раз и будут значительно увеличивать размер кода и уменьшать читаемость. –

+0

@rsanchezsaez Это должно быть хорошо. Библиотеки загружают сверху вниз, поэтому библиотека не будет иметь видимости для любых функций, которые пользователь создал (разумеется), и если библиотека не раскрывает эту функцию, тогда не должно быть столкновения с конечным приложением. Если он не будет публично публиковаться, то проблем с компоновщиками не будет. –

1

Несмотря на то, что вы хотите избежать этого решения, я подозреваю, что самый простой из них будет добавлять достаточно уникальный префикс имени этих функций (учитывая, что ни C, ни Objective-C не имеют пространства имен).

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

#define DegreesToRadians() HLDegreesToRadians() 
1

Поставь реализации функции в файле заголовка и объявить их как статические.

Например:

static UIColor *RGB(int r, int g, int b) { 
    // blah... 
} 

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

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

Приятная вещь об этом против использования макроса заключается в том, что автозаполнение все еще работает правильно, и нет никаких странностей с запятыми.

0

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

Просто прикрепите то, что видно на глобальном уровне (или пространство имен, если вы используете C++).

Я знаю, что могу определить функции «статические» и «с» в классе (классах), которые их используют, но эти функции используются во многих классах, и поэтому этот подход нарушит принцип СУХОЙ.

Возможно, это будут однострочные. Просто поместите их в закрытый заголовок и объявите их static. Затем вы можете импортировать этот заголовок в свои файлы *.m. Клиентам не нужно их видеть, а потому, что они static, вы можете опустить префикс.

Смежные вопросы