Ответ 1
Я предполагаю, что я использовал бы только UIKIT_EXTERN, если в моем проекте есть вероятность использования кода на С++, который может использовать переменную.
Right. Это основная причина. Это происходит потому, что символы C и С++ используют разные соглашения об именах.
Существует менее распространенная причина: UIKIT_EXTERN
также определяет видимость по умолчанию.
Примечание. В общем случае "символ" - не "переменная", поскольку extern
также может применяться к константам, функциям и т.д.
Если это так, не было бы безопасно объявлять все ваши внешние константы с помощью UIKIT_EXTERN?
Короткий ответ. Для использования этой формы было бы хорошей практикой (читайте: "безопасно" ), но обычно лучше всего, чтобы ваша библиотека объявила свой собственный эквивалент UIKIT_EXTERN
.
UIKIT_EXTERN
- это декларация UIKit. Библиотеки не должны зависеть от этого объявления и просто определять свой собственный синоним - и многие это делают, но я нахожу его более распространенным в C и С++, потому что эти программы часто нацелены на большее количество платформ и хороший процент Программы iOS не разработаны для поддержки других платформ. В противном случае программы Objective-C, которые не требуют UIKit, могут зависеть от UIKit из-за этого объявления, поэтому им придется импортировать UIKit (так что объявление UIKIT_EXTERN
видно).
Кроме того, UIKit недоступен на всех платформах, где могут выполняться программы iOS (т.е. это может быть C, С++ или зависит от Foundation и переносится на OS X). Поэтому даже если кто-то (любопытно) настаивал на том, чтобы объявить свои собственные, было плохой идеей, выбор CF_EXPORT
(эквивалент CoreFoundation) был бы более переносимым вариантом, поскольку он также мог использоваться для C, С++ и OS X. Кроме того, ваша библиотека необходимо было бы включить CoreFoundation (как минимум).
Если ваша библиотека зависит от UIKit, и инфраструктура должна быть импортирована вашей библиотекой, то маловероятно, что использование их синонима вызовет проблему для вашей библиотеки.
Но это довольно большой набор условий - очень легко для вашей библиотеки просто объявить свой собственный. Короче говоря, хорошо написанная и переносимая библиотека должна (почти) никогда не использовать "raw" extern
, и не должно быть ненужных зависимостей библиотек - это хорошо (UIKit в этом случае).
Было бы плохой выбор дизайна для использования UIKIT_EXTERN
, если ваша библиотека не была неотделима от UIKit - например, коллекция подклассов UIView
.
Если ваша библиотека просто использует типы Foundation, тогда импорт UIKit означает, что ваша библиотека будет (излишне) непригодной для использования в OS X (пока этот импорт UIKit не будет удален).
Люди, которые не имеют большого опыта использования С++ с C (включая надмножества), могут не знать, что имена символов различны, поэтому они могут просто использовать extern
напрямую. Наконец, некоторые программы изначально не предназначались для использования вне трансляций C и/или Objective-C, поэтому они могли просто использовать extern
без условного декодирования для перевода.
Наконец, UIKIT_EXTERN
может не делать то, что вы ожидаете/хотите, поскольку оно указывает:
- символ внешнего символа
- который имеет видимость по умолчанию
Для символов библиотеки, видимых для трансляций ObjC, это идеально.