自我变量和变量的区别

5
当我使用`@property`/`@synthesize`创建`myVariable`时,self.myVariable = obj;myVariable = obj;有什么区别?
6个回答

14

需要注意的是,点语法会被编译器转换成简单的objc_msgSend调用:也就是说,在底层它的作用与向该变量的访问器发送消息完全相同。因此,以下三种写法都是等价的:

self.myVariable = obj;

[self setMyVariable:obj];

objc_msgSend(self, @selector(setMyVariable:), obj);
当然,这意味着使用点语法实际上会导致完整的消息发送,这意味着调用一个新函数和与之相关的所有开销。相比之下,使用简单赋值(myVariable = obj;)不会产生任何开销,但当然它只能在所涉及的类的实例方法内使用。

13

@synthesize指示编译器根据.h文件中@property指令的规定生成成员变量的访问器。例如,如果指定为retain,则setter将保留该变量,如果指定为copy,则会复制它。

这些访问器(除非另有指定)将被命名为propertyName和setPropertyName。

使用“.”符号(请注意,不是上面提到的self语法)表示您希望使用访问器(如果要设置字符串并希望确保保留计数正确,则这是一个好方法)。

因此,在类实现内部:

  • self.bill = fred将调用访问器setBill。
  • bill = fred将直接设置bill为fred,而不经过访问器。

5
我开始进行Cocoa开发时发现的一个区别是,如果我使用@Property/@Synthesize语法设置变量,并且没有使用self.myVariable = obj[self setMyVariable:obj],而是使用myVariable = obj,那么如果后来释放了obj,对象就不再被保留。(假设@Property被设置为使用retain。)
原因在于使用myVariable = obj时,保留计数器没有被设置,当obj被释放时,计数器现在为零。(除非你自己保留它)但是使用访问器将为您执行保留计数器。(再次假设您在声明时设置了retain)。

4

Shyne

如果我能为此添加一条重要说明。上面的答案都很棒,所以我不会在技术方面再做补充。但是只有这个:

如果您创建了一个合成属性

@synthesize myProp;

始终使用 self.myProp 模式来设置它。

self.myProp = newVal;

这似乎非常明显,但很重要。确实没有理由这样做,但在您真正了解如何创建合成的setter之前,您只想假设您必须使用self.模式来设置值。
诚实地说:这将为您节省很多深夜调试会话。非保留内存访问违规只是最难调试的问题。

2
< p > self 语法使用访问器方法,而另一种语法则不使用。如果访问器执行的操作不仅仅是简单地分配新值,那么这可能是一个重大差异。请参阅 Objective-C 教程中的 已声明属性 部分。


2
其他答案是正确的,区别在于点表示法通过访问器而不是直接更改ivar来更改它。
在你知道自己在做什么之前,我建议你使用点表示法(例如self.propertyName = ...)。 Cocoa/Obj-C 使用了很多键值编码,虽然手机SDK没有充分利用它(比如绑定等),但最终会有所作为。现在习惯使用访问器将为您节省很多头痛的时间。
使用访问器方法还可以为您提供覆盖它们并提供更多功能的机会。仅仅更改ivar的值,您就失去了这个能力。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接