Что делает директива @package в Objective-C? - PullRequest
64 голосов
/ 21 апреля 2009

Кто-нибудь точно знает, для чего используется директива @package в Objective-C?

Единственное упоминание, которое я смог найти в Программировании в Objective-C 2.0 Стивена Кочана, было:

@ package - для 64-битных изображений переменная экземпляра может быть доступна в любом месте изображения, реализующего класс

...

Что? Это ограничено для использования с изображениями, как на картинках? Или это означает образы как образы дисков?

Это запутанное описание, и оно не раскрывает всю остальную часть книги ...

Любая помощь будет потрясающей, спасибо!

Ответы [ 2 ]

48 голосов
/ 21 апреля 2009

@package аналогично internal для .NET. Это означает, что член доступен только из структуры, в которой он определен.

Примечание: в 32-разрядной версии действует как @public.

40 голосов
/ 06 ноября 2011

Документация Apple объясняет это немного, но здесь немного подробнее ...

Переменные экземпляра, объявленные в @package, будут доступны только по коду из той же платформы, библиотеки или исполняемого файла. Это наиболее похоже на internal в C # и Friend в VB.NET, но другие языки программирования также имеют аналогичные схемы защиты (Java имеет package-private).

Например, представьте себе структуру RecipeKit.framework для управления рецептами:

@interface Recipe : NSObject {
  @package;
    NSString *name;
  @private;
    NSArray *ingredients;
}
@end

@interface RecipeController : NSObject
@end

Контроллер рецептов сможет получить доступ к названиям рецептов напрямую. Вы могли бы написать что-то подобное в RecipeController, так как это часть той же самой структуры:

Recipe *recipe = [[[Recipe alloc] init] autorelease];
[recipe->name autorelease];
recipe->name = [@"The best ever recipe!" retain];

Если вы напишите приведенный выше код в приложении, ссылающемся на RecipeKit, это вызовет ошибку компилятора, поскольку у вас нет доступа к этой переменной. Наконец, при компиляции для 32-разрядных переменных переменные, объявленные в @package, ведут себя так, как если бы они были объявлены в @public, поэтому следите за различиями здесь.

Эта новая функция получила очень мало внимания, потому что это просто еще один способ сломать инкапсуляцию вашего класса. Как всегда было верно, вам, вероятно, лучше работать только с @private переменными и иметь методы доступа для них. Фактически, какое-то время Apple пыталась добиться этого, включив @private в свои шаблоны. Со свойствами в Objective-C 2.0 придерживаться @private достаточно просто, и в зависимости от целевой платформы вы можете полностью исключить переменные экземпляров .


Изображения

Одна вещь, которую несколько предыдущих ответов оставили немного неясной, касалась аспекта изображений из исходного вопроса. Фактически, слово image, используемое в описании переменных @package, не имеет ничего общего с графическими изображениями. Вместо этого он ссылается на изображения, которые динамический компоновщик может загрузить. Обычно исполняемые файлы, каркасы и динамические библиотеки рассматриваются компоновщиком как образы (хотя они обрабатываются немного по-разному). Вы увидите, как изображение слова всплывает время от времени. Например, распространенная ошибка во время выполнения: «Изображение dyld не найдено». Вы также найдете использование слова image, разбросанного по всей документации для dyld. Прочтение справочной страницы для dyld может помочь немного прояснить двусмысленность этого слова. UIImage может объявлять переменные как @package, но это не имеет ничего общего с изображением, поскольку оно относится к исходному вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...