self.text和_text之间的真正区别

时间:2013-09-05 08:46:42

标签: iphone ios objective-c cocoa

我读了很多关于这个主题的帖子,但我完全无法理解一切。 好的,很明显

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" ?

有什么区别?

6 个答案:

答案 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"