2012-04-26 45 views
45

在调用@property时,在Objective-C中使用下划线和使用self关键字有什么区别?_和自我的区别。 in Objective-C

财产申报:

@property (weak, nonatomic) NSString *myString; 

呼吁物业@synthesize

@synthesize myString = _myString; 

是否有区别,如果我想在我的代码中使用它?什么时候?在getter/setter中?

self.myString = @"test"; 
_myString = @"test"; 
+0

'self'是一个符号。 '_'是一些符号中的字符。 'myString'和'_myString'是碰巧相关的两个不同的符号,不是因为拼写,而是因为它们被命名为相同的'@ synthezize'。 – 2012-04-26 12:37:35

+0

请尝试以下答案: http://stackoverflow.com/questions/5170631/what-does-synthesize-window-window-do – Peres 2012-04-26 12:37:57

+2

检查@乔纳森的回答这个以前的SO问题帮助的http://计算器.com/questions/5466496/why-rename-synthesized-properties-in-ios-with-leading-underscores – visakh7 2012-04-26 12:38:29

回答

68

self.myString = @"test";完全等同于编写[self setMyString:@"test"];。这两个都在调用一个方法。

你可能自己写了这个方法。它可能是这个样子:

- (void)setMyString:(NSString*)newString 
{ 
    _myString = newString; 
} 

因为你使用@synthesize,你没有真正费心编写方法,你可以让编译器把它写你。

因此,从看这种方法,它看起来像调用它会做一样的事情,只是分配一个值的实例变量,对不对?好吧,它并不那么简单。

首先,你可以编写你自己的setter方法。如果你这样做了,你的方法会被调用,并且它可以做各种附加的事情以及设置变量。在这种情况下,使用self.myString =会调用您的方法,但不会执行_myString =,因此将使用不同的功能。其次,如果你曾经使用Key Value Observing,编译器会做一些非常聪明的技巧。在幕后,它为你的课程提供了子类,并且覆盖了你的setter方法(无论是你自己写的还是通过综合生成的),以便对Key Value Observing工作所需的willChangeValueForKey:进行调用。你不需要知道它是如何工作的(尽管如果你想要一些就寝时间阅读,这很有趣),但是你需要知道,如果你想让Key Value Observing自动工作,你必须使用setter方法。

第三,即使你依靠合成来编写一个方法,也可以调用setter方法,为将来提供灵活性。当值发生变化时,您可能会想要额外做一些事情,并且在您发现要执行该操作的时候,您可以手动编写一个setter方法 - 如果您习惯于始终使用self.myString =,那么您将不会需要更改代码的其余部分以开始调用新方法!

第四,这同样适用于子类。如果其他人是你的代码的子类,如果你使用setter,那么他们可以覆盖它们来调整功能。

任何时候直接访问实例变量,都明确地没有提供一种方法让额外的功能在这一点上被吸引。既然你或其他人可能想要在将来使用这些功能,除非有充分理由不这样做,否则一直都在使用setter。

+0

请注意,我没有提到内存管理的含义。如果你使用的是ARC,在这种情况下它们的相关性就会降低很多,所以我跳过了它们。 – 2012-04-26 12:50:29

+0

好解释:) – iTag 2014-10-10 16:35:51

+0

顺便说一下,关于第一句话......这是真实的99%的时间,但如果你有一个自定义setter(在属性声明中用'setter ='指定),那么这两个表单并不完全等同。 – 2016-03-22 04:08:23

8

你是正确的 - 第一个版本(self.myString)调用合成的getter/setter和私有成员变量直接在第二个版本的访问。

它看起来像你正在使用ARC,所以在这种情况下,它没有多大的区别。但是,如果您未使用ARC,则可能会有所作为,因为直接分配给私有成员不会触发使用synthesize为您生成的自动保留/释放或复制/释放逻辑。

+0

他们是两个不同的符号。其中一个可能是“土豚”,另一个可能是“斑马”,并且仍然具有变量设置/吸气关系。 – 2012-04-26 12:39:29

+0

@热舔 - 你的名字是无关紧要的,但是当我读到这个问题时,我想他想知道使用综合属性与仅使用支持它的成员变量之间的实际区别。 – 2012-04-26 12:41:28

+0

@EricPetroelje - 是的,那正是我所问的。谢谢! – Kuba 2012-04-26 12:45:25

3

_(下划线)只是一个约定,如this question中所述。

当您不使用self.前缀属性访问时,您正在直接访问基础变量,如在c struct中。一般来说,你只能在init方法和自定义属性访问器中这样做。这允许像计算属性和KVC按预期工作。

相关问题