【发布时间】:2010-10-06 21:19:47
【问题描述】:
当我使用@propery/@synthesize创建`myVariable时,self.myVariable = obj;和myVariable = obj;有什么区别?
【问题讨论】:
标签: objective-c cocoa-touch cocoa declared-property
当我使用@propery/@synthesize创建`myVariable时,self.myVariable = obj;和myVariable = obj;有什么区别?
【问题讨论】:
标签: objective-c cocoa-touch cocoa declared-property
self 语法使用访问器方法,其他语法不使用。如果访问者所做的不仅仅是分配新值,这可能是一个很大的区别。请参阅 Objective-C 教程的 Declared Properties 部分。
【讨论】:
@synthesize 指令告诉编译器根据 .h 文件中 @property 指令中给出的规范为您的成员变量生成访问器。 (即如果你指定retain,setter会保留变量,如果你指定copy,它会复制它。)
访问器将(除非您另外指定)命名为 propertyName 和 setPropertyName。
使用 .表示法(注意,不是上面所说的 self 语法)表示您要使用访问器(例如,如果您正在设置字符串并希望确保保留计数正确,这是一件好事)。
所以,在你的类实现中:
【讨论】:
其他答案都是正确的,不同的是点符号导致ivar通过附件而不是直接更改。
在您知道自己在做什么之前,我建议您使用点表示法(即self.propertyName = ...)。 Cocoa/Obj-C 在键值编码方面做了很多工作,虽然手机 SDK 没有充分利用这一点(比如绑定),但最终它会。现在习惯使用访问器,以后会省去很多麻烦。
使用访问器方法还可以让您有机会覆盖它们并在需要时提供更多功能。通过简单地更改 ivar 的值,您就失去了这种能力。
【讨论】:
我在开始 Cocoa 开发时发现的一个区别是,如果我将变量设置为使用 @Property/@Synthesize 语法并且我没有使用 self.myVariable = obj 或 [self setMyVariable:obj] 而是 myVariable = obj,如果稍后释放 obj,则不会保留该对象。 (假设 @Property 设置为使用保留。)
原因是使用 myVariable = obj 时未设置保留计数,当释放 obj 时计数现在为零。 (除非你自己保留它)但是通过使用访问器它会为你做保留计数。 (再次假设您在声明时将其设置为使用保留)。
【讨论】:
请务必注意,编译器将点语法转换为简单的 objc_msgSend 调用:也就是说,在它下面的行为与向该变量的访问器发送消息完全一样。因此,以下三个都是等价的:
self.myVariable = obj;
[self setMyVariable:obj];
objc_msgSend(self, @selector(setMyVariable:), obj);
当然,这意味着使用点语法实际上会导致完整的消息发送,这意味着调用一个新函数以及与之相关的所有开销。相比之下,使用简单赋值 (myVariable = obj;) 不会产生这种开销,但它当然只能在相关类的实例方法中使用。
【讨论】:
谢恩
如果我可以为此添加一个重要说明。上面的答案都很棒,所以我不会添加到技术方面。但就是这样:
如果您创建合成属性
@synthesize myProp;
始终使用 self.myProp 模式来设置它。
self.myProp = newVal;
这看起来很明显,但很重要。确实没有理由这样做,但是在您真正了解合成 setter 是如何创建的之前,您只想假设您必须使用 self。模式来设置值。
诚实:这将为您节省大量深夜调试会话。非保留内存访问违规是最难调试的。
【讨论】: