Объективное свойство 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];

Вы не использовали свойство, поэтому номер не сохраняется. Это делает существенную разницу между использованием аксессуаров и синтезированными свойствами.