2010-03-30 8 views
5

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

В «субъективном» C я могу объявить переменную в моем .c файле, и она не видна вне этой единицы компиляции. Я могу объявить его в соответствующем файле .h, а затем любой, кто ссылается в этом модуле компиляции, может увидеть эту переменную.

Интересно, есть ли эквивалентный выбор в Objective-C или если я действительно должен объявить каждый ivar в .h для моего класса.

Ari.

+3

+1, и для примечания субъективного-C. –

ответ

2

Ари,

Хорошая ссылка, как выполнить «невидимые» объявления переменных экземпляра может be found here с кредитом почтительно дал Мэтт Галлахер.

Надежда это помогает, Frank

+0

Право. Бит, который на самом деле отвечает на мой вопрос, заключается в том, что я могу поместить часть @interface в мой .m-файл. Спасибо за указатель. – iter

0

Чтобы ограничить доступ, вы можете использовать @private или @protected ключевые слова:

@interface Foo : NSObject { 
    @private 
    int barPrivate; 

    @protected 
    int barProtected; 

    @public 
    int barPublic; 
} 
@end 

EDIT:Царапины все, оказывается, мне действительно нужно немного поспать.

+0

Правильно, вы не можете добавить переменные экземпляра с категорией. – codewarrior

+0

Да, я помнил это сразу после того, как я опубликовал ответ. –

+0

Создайте несколько экземпляров с разными значениями для 'bar', и вы увидите -' bar' - глобальная переменная. – Chuck

2

Переменные экземпляра традиционно необходимы для определения размера класса. Всегда было плохой практикой напрямую обращаться к иварам, и это не главное. В современной среде это менее необходимо, но, во всяком случае, это не утечка абстракции, если клиенты не полагаются на ivars класса, что должно быть невозможно, поскольку вы объявляете их как @protected или @private, правильно?

+0

Благодарим вас за то, что вы указали оригинальное позитивное намерение явно перечислить иваров. Я так долго использовал по-настоящему динамические языки (Python, Lisp), забыл, что некоторые языки хотят знать размеры во время компиляции. Во многом изучение Objective-C похоже на поездку вниз по полосе памяти. Или вниз по шахте шахты: я добираюсь, чтобы увидеть все различные слои осадка, которые накапливаются на языке за всю его жизнь. – iter

+0

@iter: В Objective-C больше нет необходимости. Современная среда исполнения работает так же, как Python, где переменные экземпляра могут быть назначены все волей-неволей, не объявляясь в заголовке, но язык по-прежнему связан с синтаксисом его прошлого. – Chuck

+0

Я думаю, что, возможно, я столкнулся с этим на днях, когда я начал сталкиваться с прерывистыми ошибками objc_msgSend_fixup. Я не уверен на 100%, но проблема исчезла, когда я удалил object_setClass, который я использовал для передачи объекта в пользовательский класс с добавленными свойствами. –

0

Ивар являются @protected по умолчанию (хотя @private и @protected не гарантируют, что другие классы не могут получить к ним доступ - вы всегда можете получить доступ к Ивар с getValue:forKey:). Вы никогда не должны напрямую обращаться к ivars из других классов напрямую в любом случае - «выбор» заключается в том, следует ли раскрывать ivars как свойства (вам просто нужно полагаться на все классы, следующие за соглашением, чтобы напрямую не обращаться к ivars).

В новой версии run-времени объектива вам не нужно вообще объявлять ivars, так как они могут быть синтезированы во время выполнения, но, к сожалению, это не работает с симулятором iPhone, поэтому на данный момент это лучше всего объявить все ivars в файле .h.

+0

Я меньше беспокоюсь о том, чтобы не допустить, чтобы код клиента делал что-то странное с моим кодом, и больше о том, чтобы рассказать клиенту-программисту больше о моей реализации, чем он хочет знать. Когда я прочитал файл .h, я хочу узнать «внешнюю» форму библиотеки, которую я использую. Если я хочу знать его внутреннюю работу, я читаю .c или .m в зависимости от ситуации. Мне нравится держать эти два разных и отдельных. – iter

+1

Я согласен - это раздражает, что ivars находятся в файле .h, но, как упоминалось выше, я думаю, что это в интересах компилятора. – shosti