_和自我的区别。 在Objective-C中
在调用@property
时,在Objective-C中使用下划线和使用self
关键字有什么区别?
财产声明:
@property (weak, nonatomic) NSString *myString;
在属性上调用@synthesize
:
@synthesize myString = _myString;
如果我想在我的代码中使用它,是否有区别? 什么时候? 在getter / setter?
self.myString = @"test"; _myString = @"test";
self.myString = @"test";
完全等同于写[self setMyString:@"test"];
。 这两个都在调用一个方法。
你可以自己写这个方法。 它可能看起来像这样:
- (void)setMyString:(NSString*)newString { _myString = newString; }
因为你使用了@synthesize
,所以你不必费心写这个方法,你可以让编译器为你编写它。
所以,从这个方法看,它看起来像调用一个值的实例variables,完全相同的事情吧? 那么这不是那么简单。
首先,你可以编写你自己的setter方法。 如果你这样做,你的方法会被调用,并且可以做各种额外的事情,以及设置variables。 在这种情况下,使用self.myString =
会调用你的方法,但是_myString =
不会,因此将使用不同的function。
其次,如果你使用关键值观察,编译器会做一些非常聪明的技巧。 在幕后,它为你的类子类,并且覆盖你的setter方法(无论是你自己写的还是通过综合生成的),以便调用willChangeValueForKey:
key value Observing需要的工作。 你不需要知道这是如何工作的(尽pipe如果你想要一些睡前阅读,这是非常有趣的),但是你需要知道,如果你想让Key Value Observing自动工作,你必须使用setter方法。
第三,即使你依靠合成来编写一个方法,也可以调用setter方法,为将来提供灵活性。 当值发生变化时,你可能会想要额外的做一些事情,当你发现你想要做的时候,你可以手动编写一个setter方法 – 如果你总是习惯使用self.myString =
,那么你将不需要更改其余的代码来开始调用新的方法!
第四,这同样适用于子类。 如果别人是你的代码的子类,如果你使用setter,那么他们可以覆盖它们来调整function。
任何时候你直接访问实例variables,你都明确地没有提供一个额外的function,在这一点上被吸引。 既然你或者其他人可能想在将来使用这样的function,除非有充分的理由,否则一直都在使用setter。
你是对的 – 第一个版本( self.myString
)调用合成的getter / setter,第二个版本直接访问私有成员variables。
看起来你正在使用ARC,所以在这种情况下,它并没有太大的区别。 但是,如果您没有使用ARC,则直接分配给私有成员将不会触发使用synthesize
为您生成的自动保留/释放或复制/释放逻辑。
_
(下划线)仅仅是一个约定,就像这个问题所解释的那样。
当你不用自己前缀一个属性访问self.
,你直接访问底层variables,就像在ac struct
。 一般来说,你只能在init方法和自定义属性访问器中这样做。 这允许像计算属性和KVC的东西按预期工作。