给出以下属性声明:
@property NSInteger foo;
增量,减量和复合赋值运算符如何实际适用于self.foo
?
据我了解,self.foo
仅仅是实际存取方法的语法糖。因此self.foo
不能直接访问名为NSInteger
的{{1}}变量,而是直接调用:
foo
或
- (void)setFoo:(NSInteger)foo;
然而,下面的一组代码非常好,没有标记,编译得很好,并且完全返回预期的结果:
- (NSInteger)foo;
而且我认为假设前后修复操作符以及其他9个复合操作符的递减将完全按照您在{{直接使用它们'时所期望的那样做,这可能是安全的。 {1}}变量。
如果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
真的只是我上面提到的两种方法的语法糖,我就不明白为什么它会起作用。
如果我覆盖默认访问器以包含NSInteger
语句,那么我可以看到每个语句被调用以及具有什么值,我可以看到首先调用getter然后调用setter。
这是否意味着以下内容:
self.foo
实际上被替换为:
NSLog
在预编译期间?
编辑:因此,在汇编级别,self.foo += 1;
和[self setFoo:([self foo] + 1)];
之间是否存在差异?如果我们不是在谈论某个属性,并且self.foo += 1;
只是一个常规的int,那么在self.foo = self.foo + 1;
和bar
之间会有什么区别呢?
答案 0 :(得分:6)
完全。你的假设是正确的。您可以自己实现属性并添加日志以再次检查您的假设
在@interface部分:
@property(nonatomic) NSInteger foo;
// nonatomic keyword is not really required but
// it is better to add it since we will implement
// property as nonatomic
在@implementation部分:
- (void)setFoo:(NSInteger)foo
{
_foo = foo; // _foo variable is implicitly generated by compiler
NSLog(@"set foo %d", _foo);
}
- (NSInteger)foo
{
NSLog(@"get foo %d", _foo);
return _foo;
}
然后运行
self.foo = 0;
self.foo += 1;
你应该在调试窗口中收到:
set foo 0
get foo 0
set foo 1
更新:
self.foo += 1;
和self.foo = self.foo + 1;
之间有什么区别吗?”没有。两个[self setFoo:([self foo] + 1)];
都会被调用。
bar += 1;
和bar = bar + 1;
之间会有区别吗?是。但只有在关闭编译时优化时才会这样做。
bar += 1;
更快。它将被编译为类似:
mov eax,dword ptr [bar]
inc eax // difference is here!
mov dword ptr [bar],eax
bar = bar + 1;
来:
mov eax,dword ptr [bar]
add eax,1 // difference is here!
mov dword ptr [bar],eax