ObjC 属性和 C 运算符
Posted
技术标签:
【中文标题】ObjC 属性和 C 运算符【英文标题】:ObjC properties and C operators 【发布时间】:2014-06-18 12:03:35 【问题描述】:给定以下属性声明:
@property NSInteger foo;
递增、递减和复合赋值运算符实际上是如何在self.foo
上工作的?
据我了解,self.foo
只是实际访问器方法的语法糖。所以self.foo
不是直接访问一个名为foo
的NSInteger
变量,而是调用其中一个:
- (void)setFoo:(NSInteger)foo;
或
- (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
而且我认为,如果您直接在 NSInteger
变量上使用它们,那么假设递减 pre 和 post fix 运算符以及其他 9 个复合运算符将完全符合您的预期,这可能是安全的。
如果self.foo
真的只是我上面提到的两种方法的语法糖,我只是不明白为什么它会起作用。
如果我覆盖默认访问器以包含 NSLog
语句,以便我可以查看每个语句的调用时间和值,我可以看到先调用 getter,然后调用 setter。
这是否意味着:
self.foo += 1;
实际上被替换为:
[self setFoo:([self foo] + 1)];
在预编译期间?
编辑:那么,在汇编级别,self.foo += 1;
和 self.foo = self.foo + 1;
之间有什么区别吗?如果我们不是在谈论属性,而bar
只是一个常规的 int,那么在汇编级别,bar += 1;
和 bar = bar + 1;
之间是否有区别?
【问题讨论】:
没错。你的假设是正确的。 鉴于结果,很明显您的假设是正确的。 我在我的问题中添加了一个附录,试图澄清我的实际意思。 @nhgrif 我已将您的问题的答案添加到我的帖子中。请检查。 【参考方案1】:没错。你的假设是正确的。您可以自己实现属性并添加日志记录以再次检查您的假设
在您的@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
【讨论】:
因此,如果您期望复合运算符的行为与在其他语言中的行为相同,那么复合运算符对 Objective-C 属性有点误导。我可以假设具有递增/递减运算符的非属性具有相同的装配差异吗? @nhgrif 不确定我是否理解正确。你能澄清你的问题吗?self.someVar++
、someVar++
、++self.someVar
、++someVar
以及减号。
@nhgrif 是的,他们都有相同的行为。以上是关于ObjC 属性和 C 运算符的主要内容,如果未能解决你的问题,请参考以下文章