Учитывая следующее объявление свойства:
@property NSInteger foo;
Как операторы инкремента, декремента и составного присваивания действительно работают с self.foo
?
Насколько я понимаю, self.foo
был просто синтаксическим сахаром для фактических методов доступа. Таким образом, self.foo
не обращается напрямую к NSInteger
переменной с именем foo
, а вызывает либо:
- (void)setFoo:(NSInteger)foo;
or
- (NSInteger)foo;
Тем не менее, следующий набор кода прекрасен, не помечен, компилируется и возвращает точно ожидаемые результаты:
self.foo = 0;
NSLog(@"%d",self.foo); // prints 0
self.foo += 1;
NSLog(@"%d",self.foo); // prints 1
self.foo++;
NSLog(@"%d",self.foo); // prints 2
++self.foo;
NSLog(@"%d",self.foo); // prints 3
И я думаю, что, вероятно, можно с уверенностью предположить, что операторы декремента до и после исправления, а также другие 9 составных операторов будут делать именно то, что вы ожидаете, если бы вы использовали их непосредственно в переменной NSInteger
.
Я просто не понимаю, ПОЧЕМУ это работает, если self.foo
действительно просто синтаксический сахар для двух упомянутых выше методов.
Если я перезапишу средства доступа по умолчанию, чтобы включить операторы NSLog
, чтобы я мог видеть, когда каждый из них вызывается и с какими значениями, я вижу, что сначала вызывается метод получения, а затем вызывается метод установки.
Означает ли это, что следующее:
self.foo += 1;
эффективно заменяется на это:
[self setFoo:([self foo] + 1)];
во время прекомпиляции?
РЕДАКТИРОВАТЬ: Итак, на уровне сборки есть ли разница между self.foo += 1;
и self.foo = self.foo + 1;
? Что, если мы не говорим о свойстве, а bar
- это просто обычное целое число, есть ли на уровне сборки разница между bar += 1;
и bar = bar + 1;
?