我读了很多关于这个主题的帖子,但我完全无法理解一切。 好的,很明显
self.text = @"MyText" will call the accessory method setText (autogenerated)
_text = @"MyText" will still assign the value but will not call the setText
这很清楚。
但是当我们不使用ARC时,这可能很有用,因为setText将负责内存管理。但是当我们使用ARC时会发生什么? 有时如果我使用_text一切正常,有时候如果我不使用“self.text”,我的应用程序将无效。
那么真正的区别是什么?必须有的不仅仅是内存管理。
让我说我有这个
@interface MyClass:NSObject {
NSMutableString *text;
}
@property (nonatomic ) NSMutableString *text;
在这种情况下不是相同的调用
self.text = @"ok"
或
text = @"ok" ?
有什么区别?
答案 0 :(得分:7)
该属性的基础实例变量实际上是_text。这就是自动合成属性的工作原理。
但是,您应该考虑使用访问器来设置属性(使用self.text =代替)。有关Reason to use ivars vs properties in objective c
的更多信息,请参阅此链接答案 1 :(得分:4)
self.text
是[self text]
(或[self setText:...]
的语法糖,如果在作业的左侧),则是一条消息;当它自动生成(“合成”)时,它将返回连接的实例变量的值。 _text
是此实例变量。
您只能访问类中的实例变量。您可以从任何地方发送消息。如果有一天你希望修改text属性的内部工作,那么这种区别很重要,这样它就不会简单地返回局部变量的值。
答案 2 :(得分:4)
答案真的是Do I need variable and property at the same time?
当你@property实际上你正在创建访问和变异的方法以及实例变量时。
所以当你有@property(非原子,强)NSString *文本时;你创建了一个iVar _text和两个方法:
self.text; //will call -(NSString *)text;
self.text = @"text here"; //is calling -(void)setText:(NSString *)text;
@property用于去除锅炉板代码,它减少了编写类所需的代码行数。
当然有时在ARC环境中调用self.text = @“ok”和_text = @“ok”是正常的,但是你没有得到 - (NSString *)文本; - (void)setText:(NSString *)text;在您的公共头文件中。
此外,调用self.text和self.text =或它们的等价物[self text] [self setText:]通常是一种很好的做法,因为你可能已经覆盖了文本实现:
-(NSString *)text{
return [NSString stringWithFormat@"%@.jpg", _text];
}
-(void)setText:(NSString *)text{
_text = [NSString stringWithFormat:@"DW%@", text];
}
所以当你这样做时:
self.text = @"HelloThere";
NSLog (@"%@", self.text); //This will return DWHelloThere.jpg
NSLog (@"%@", _text); //Will return DWHelloThere
//whereas
_text = @"HelloThere";
NSLog (@"%@", _text); //Will return HelloThere
因此@property可以为您节省大约8行代码,让您自己的类保持整洁,如果需要,您可以覆盖访问器和更改器。但是由于后一点,它的好习惯是调用self.text和self.text = @“so so so”而不仅仅是访问iVar本身。
答案 3 :(得分:2)
从概念上讲,区别仅在于,在一种情况下,消息被发送到对象,或者单个ivar在另一种情况下被更改。如果您使用它,内存管理故事只是ARC为您处理的必要内容。
如果你对道德故事感兴趣,那么请阅读Jon Reid的帖子: Objective-C中的点符号:100%纯粹的邪恶 http://qualitycoding.org/dot-notation/
旁注:只要可以,请使用ARC。在大多数情况下,它会自动处理保留 - 释放周期(但是应该小心处理自身块中的自我。)如果使用ARC,两种方法之间没有区别,保留计数将被正确处理。正如您所描述的,如果没有ARC,您必须确保在属性设置之后必须释放对象,而在访问ivar时则不需要这样做。本文将介绍有关某些实践的更多信息: Objective-C中的属性和内存管理 http://www.whilethis.com/2011/04/properties-and-memory-management-in-objective-c/
答案 4 :(得分:1)
真正的区别在于:
在代码中创建实例时,您有一个名为text的变量。 相反,当你在文本上使用属性时,它将创建一个名为_text的iVar。
你可以想象,调用一个或另一个,将是一个很大的区别,因为它们是两个完全不同的变量
答案 5 :(得分:1)
self.text = @"Something"
使用访问者方法_text
访问私有变量[self setText:@"Something"]
。点符号只是一个语法糖。此方法可以有自己的实现,只需设置私有变量_text
的值即可添加额外的功能。
_text = @"Something"
直接将值设置为私有变量。
此外,在类实现之外设置text
属性的值时,会自动调用访问者[instance setText:@"Something"]
来设置私有变量的值
让我向您展示一些可能有区别的简单示例。方法实现很简单,仅用于教育目的,因此在实际代码中可能没有意义: - )
想象一下,每当text
属性的值发生变化时,您都希望将消息记录到控制台。您可以通过覆盖这样的访问器方法- (void)setText:(NSString *)text
来完成此操作,例如:
- (void)setText:(NSString *)text
{
// You can do whatever you want with the input "text" value, validate the value for example
// Here we just log the text was changed
// In the log message, we still have the old value of the "text" in the private variable "_text"
// so we can log it together with the new value
NSLog(@"Value of \"text\" property changed from \"%@\" to \"%@\"", _text, text);
// Set the new value of the private variable
_text = text;
// From here on, the private variable already has new value and the log line above
// would give the same values between from and to quotes
NSLog(@"Value of \"text\" property is now \"%@\"", _text);
}
因此,当您直接设置_text
时,不会执行上述任何日志消息,因为您直接访问该变量。
另一方面,使用访问方法self.text = @"Something"
进行设置会导致以下内容打印到控制台:
Value of "text" property changed from "(null)" to "Something"
Value of "text" property is now "Something"