Когда я делаю небольшой iOS API с открытым исходным кодом, как я могу учесть пользователей ARC и других пользователей? - PullRequest
2 голосов
/ 08 января 2012

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

Метод, который я думал, заключался в использовании флага компилятора: (см. этот вопрос)

#if __has_feature(objc_arc)   

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

  • Есть ли недостатки в этом способе?

  • Есть ли лучший способ сделать это?

Ответы [ 3 ]

5 голосов
/ 08 января 2012

Хотя ответ Дейва верен, существует альтернативный шаблон, позволяющий избежать необходимости поддерживать две модели памяти в вашем коде.

А именно, скомпилируйте свой код с ARC и либо:

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

  • включить ARC только для файлов при добавлении к любой цели в целевом проекте. ARC можно включить для каждого файла.

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

5 голосов
/ 08 января 2012

Вот как я это делаю. У меня также есть несколько макросов , так что мой код остается относительно «чистым»:

#if __has_feature(objc_arc)

#define DD_HAS_ARC 1
#define DD_RETAIN(_o) (_o)
#define DD_RELEASE(_o) 
#define DD_AUTORELEASE(_o) (_o)

#else

#define DD_HAS_ARC 0
#define DD_RETAIN(_o) [(_o) retain]
#define DD_RELEASE(_o) [(_o) release]
#define DD_AUTORELEASE(_o) [(_o) autorelease]

#endif

С ними я могу делать такие вещи, как:

return DD_AUTORELEASE(DD_RETAIN(_myIvar));

Или:

DD_RELEASE(_myIvar);
_myIvar = DD_RETAIN(newObject);

Или:

- (void)dealloc {
  DD_RELEASE(_myIvar);

  #if !DD_HAS_ARC
  [super dealloc];
  #endif
}

А затем макрос расширяется до правильного кода в зависимости от того, компилирую я с ARC или нет.

2 голосов
/ 08 января 2012

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

В итоге, вы можете разработать библиотеку на основе ARC и без проблем использовать ее в проектах, не относящихся к ARC (и наоборот).

...