ios _ 和自己的区别。在 Objective-C 中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10333495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between _ and self. in Objective-C
提问by Jakub
Is there a difference between using the underscore and using the self
keyword in Objective-C when calling an @property
?
self
调用@property
?时使用下划线和在 Objective-C 中使用关键字有区别吗?
Property declaration:
财产声明:
@property (weak, nonatomic) NSString *myString;
Calling @synthesize
on the property:
调用@synthesize
属性:
@synthesize myString = _myString;
Is there a difference if I want to use it in my code? When? In the getter/setter?
如果我想在我的代码中使用它有什么区别吗?什么时候?在吸气剂/二传手?
self.myString = @"test";
_myString = @"test";
回答by Amy Worrall
self.myString = @"test";
is exactly equivalent to writing [self setMyString:@"test"];
. Both of these are calling a method.
self.myString = @"test";
完全等同于写作[self setMyString:@"test"];
。这两个都在调用一个方法。
You could have written that method yourself. It might look something like this:
您可以自己编写该方法。它可能看起来像这样:
- (void)setMyString:(NSString*)newString
{
_myString = newString;
}
Because you used @synthesize
, you don't have to actually bother writing that method, you can just allow the compiler to write it for you.
因为您使用了@synthesize
,所以您实际上不必费心编写该方法,您只需让编译器为您编写即可。
So, from looking at that method, it looks like calling it will do the exact same thing as just assigning a value to the instance variable, right? Well, it's not so simple.
因此,从该方法的角度来看,调用它似乎与为实例变量赋值完全相同,对吗?嗯,事情没那么简单。
Firstly, you could write your own setter method. If you do so, your method would get called, and it could do all sorts of additional things as well as setting the variable. In that case, using self.myString =
would call your method, but doing _myString =
would not, and thus different functionality would be used.
首先,您可以编写自己的 setter 方法。如果你这样做,你的方法将被调用,它可以做各种额外的事情以及设置变量。在这种情况下, usingself.myString =
会调用您的方法,但 do_myString =
不会,因此将使用不同的功能。
Secondly, if you ever use Key Value Observing, the compiler does some very clever tricks. Behind the scenes, it subclasses your class, and overrides your setter method (whether it's one you wrote yourself or one generated by synthesize), in order to make the calls to willChangeValueForKey:
that are needed for Key Value Observing to work. You don't need to know how this works (although it's quite interesting if you want some bedtime reading!), but you do need to know that if you want Key Value Observing to work automatically, you have to use setter methods.
其次,如果你使用过 Key Value Observing,编译器会做一些非常聪明的技巧。在幕后,它子类化您的类,并覆盖您的 setter 方法(无论是您自己编写的方法还是合成生成的方法),以便调用willChangeValueForKey:
键值观察工作所需的方法。您不需要知道它是如何工作的(尽管如果您想在睡前阅读它会很有趣!),但是您确实需要知道,如果您希望 Key Value Observing 自动工作,则必须使用 setter 方法。
Thirdly, calling the setter method even if you're relying on synthesize to write one gives you flexibility for the future. You might want to do something extra whenever a value is changed, and at the point you discover you want to do that, you can manually write a setter method —?if you're in the habit of always using self.myString =
, then you won't need to change the rest of your code to start calling the new method!
第三,调用 setter 方法,即使您依赖合成来编写,也可以为您提供未来的灵活性。你可能想要在值改变时做一些额外的事情,当你发现你想要这样做时,你可以手动编写一个 setter 方法——如果你习惯于总是使用self.myString =
,那么你不会需要更改其余代码以开始调用新方法!
Fourthly, the same applies to subclasses. If someone else was to subclass your code, if you use the setters then they could override them to adjust the functionality.
第四,这同样适用于子类。如果其他人要对您的代码进行子类化,如果您使用 setter,那么他们可以覆盖它们以调整功能。
Any time you access the instance variable directly, you're explicitly not providing a way for extra functionality to be hooked in at that point. Since you or someone else might want to hook in such functionality in the future, it pays to use the setters all the time, unless there's a good reason not to.
任何时候直接访问实例变量时,您都明确没有提供一种方法来挂接额外的功能。由于您或其他人将来可能希望使用此类功能,因此一直使用 setter 是值得的,除非有充分的理由不这样做。
回答by Eric Petroelje
You are correct - the first version (self.myString
) calls the synthesized getter/setter and the second version access the private member variable directly.
您是对的 - 第一个版本 ( self.myString
) 调用合成的 getter/setter,第二个版本直接访问私有成员变量。
It looks like you are using ARC, so in that case it doesn't make that much of a difference. However, if you aren't using ARC, it can make a difference as assigning to the private member directly won't trigger the automatic retain/release or copy/release logic that is generated for you by using synthesize
.
看起来您正在使用 ARC,因此在这种情况下,它没有太大区别。但是,如果您不使用 ARC,它会有所作为,因为直接分配给私有成员不会触发使用synthesize
.
回答by Gil
The _
(underscore) is simply a convention, as explained in this question.
该_
(下划线)仅仅是一个惯例,在解释这个问题。
When you don't prefix a property access with self.
, you are accessing the underlying variable directly, as in a c struct
. In general, you should only ever do this in your init methods and in custom property accessors. This allows stuff like computed properties and KVCto work as intended.
当您不使用 前缀访问属性时self.
,您将直接访问基础变量,如 ac struct
。通常,您应该只在 init 方法和自定义属性访问器中执行此操作。这允许诸如计算属性和KVC 之类的东西按预期工作。
回答by JFCa
There is a tip not mentionend, the access using underscore is faster and the access using self is safer (KVC). Maybe this can summarise when you have to use each one.
还有一个小技巧没有提到,使用下划线的访问速度更快,使用 self 的访问更安全(KVC)。也许这可以总结您何时必须使用每一个。