Объективное свойство C подчеркивания vs self
Я играю со стандартным представлением с разметкой, созданным при выборе приложения с разделенным представлением в Xcode, и после добавления нескольких полей мне нужно было добавить несколько полей, чтобы отобразить их в подробном представлении.
и что-то интересное
в исходном образце мастер-представление задает свойство detailItem в подробном представлении, и на нем отображается подробное представление.
- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
Я понимаю, что это делает и все, поэтому пока я играл с ним. Я думал, что это будет то же самое, если вместо _detailItem я использовал self.detailItem, так как это свойство класса.
однако, когда я использовал
self.detailItem != newDetailItem
Я действительно застрял в цикле, где этот метод постоянно называется, и я не могу сделать что-либо еще в симуляторе.
Мой вопрос: какова фактическая разница между значениями подчеркивания (ivar?) и свойствами?
Я читаю некоторые сообщения здесь, это, кажется, всего лишь объективная конвенция C, но на самом деле это имело какое-то значение.
Ответы
Ответ 1
В ходе вашего эксперимента вы настроили бесконечный цикл, поэтому симулятор не реагирует.
Вызов self.detailItem
в пределах setDetailItem:
вызывает setDetailItem:
рекурсивно, так как ваш класс реализует собственный метод настройки для свойства detailItem
.
Я хотел бы отнести вас к документации Apple по объявленным свойствам для совка по свойствам, ivars и т.д.; но вкратце, объявленные свойства являются упрощенным способом предоставления методов доступа для вашего класса. Вместо того, чтобы писать собственные методы доступа (как это было до Objective-C 2.0), они теперь генерируются для вас через синтаксис свойств.
Ответ 2
_property
означает, что вы напрямую получаете доступ к свойству.
self.property
означает, что вы используете аксессоры.
В вашем случае в методе setter вы вызываете его, создавая рекурсивный вызов.
Ответ 3
Свойства в основном являются способом компилятора генерировать setter и getter для данной переменной экземпляра.
Итак, когда вы используете что-то вроде:
id detailItem = self.detailItem;
что вы делаете под капотом:
id detailItem = [self detailItem];
То же самое для:
self.detailItem = otherDetailItem;
:
[self setDetailItem:otherDetailItem];
Поэтому, когда вы сами пишете установщик, вы попадаете в бесконечный цикл, так как вы сами получаете доступ к самому методу.
Вы можете свободно использовать "я". нотация в вашем классе, просто не тогда, когда вы переопределяете сеттер или аксессуар из-за описанного выше механизма.
Случаи в классе, в котором я использую. нотация по простому доступу к ivar - это когда я изменяю значение, вы никогда не знаете внутри своего класса, что должно произойти, когда вы меняете значение. есть ли у вас что-то в плане статуса, который должен уведомить какого-либо делегата о статусе изменения? Обычно это не так, просто используя. вы убедитесь, что в будущем вам не придется реорганизовывать какой-либо код, если вы решили сделать какую-то магию в методе setter.
Ответ 4
Я приведу пример (без разрешения ARC):
@property (nonatomic, retain) NSNumber* number;
Если вы не синтезируете его, вы можете получить к нему доступ следующим образом:
self.number= [NSNumber numberWithBool: YES];
В этом случае номер сохраняется. Если вы его синтезируете и не используете свойство:
@synthesize number;
Позже в файле:
number=[NSNUmber numberWithBool: YES];
Вы не использовали свойство, поэтому номер не сохраняется. Это делает существенную разницу между использованием аксессуаров и синтезированными свойствами.