iOS,使用下划线直接使用iVar

时间:2013-03-26 18:10:09

标签: iphone ios objective-c cocoa-touch ivar

这已被问了很多,但这个问题是要举例说明何时使用这些方法。请使用setter和getter无限循环以外的示例

例子。

.h -
    @property(nonatomic, strong)NSMutableArray* mutArray
.m -
    @synthesize mutArray= _mutArray;
    

1)我想要:
    _mutArray = [[NSMutableArray alloc] init];
OR
    self.mutArray=[[NSMutableArray alloc] init];
为什么我会做他们每个人,有什么区别?!

2)如果我想添加一个对象...
    [_mutArray addObject:object];
OR
        [self.mutArray addobject:object];

为什么?!

非常感谢!

3 个答案:

答案 0 :(得分:12)

您应该只在initdealloc中处理您的ivars,或者在实现细节绝对需要的地方(例如访问者本身内部,或实际需要内存地址的地方)。除了在这些地方,您应该始终使用访问者,这意味着[self foo]而不是_foo

self.foo只是实际调用的语法糖,即[self foo]。重要的是要理解self.foo是标准的ObjC消息发送,并且与[self foo]完全相同。按照惯例,您只应在引用属性时使用点语法。

预ARC,根据我的经验,直接使用ivars是导致崩溃的首要原因。在没有ARC的情况下直接分配到ivar时,你搞砸的可能性很快超过了程序范围的100%。

自ARC以来,我仍然认为你应该总是使用访问器(除了上面给出的例外),但原因更为微妙。它的主要原因是可以在当前类,子类中或通过KVO(完全在代码之外发生)自定义访问器。如果您直接访问ivar,那么您将绕过它。例如,假设该属性是懒惰创建的(这很常见)。然后,如果您在创建之前使用ivar,您将获得微妙的错误。因此,您必须记住,对于该属性,始终使用访问者。同样,您可以致电setNeedsDisplay或发布通知等。

如果你有一个简单的规则,说“我将永远使用访问者”,那么很容易看到代码并知道它是正确的。在少数情况下你需要规避访问者,_说“嘿,请注意这里,我做的事情很奇怪。”

如果您有一个规则“我将使用访问器来处理需要它的属性,而不是那些不需要它的属性”,那么几乎不可能查看代码并知道它是否正确。以前的开发人员是否使用了ivar,因为它是必需的,或者只是因为他觉得这样?你能改变它吗?这很难知道。

所以即使是在ARC之后,使用访问器仍然是很好的防御性编程,我强烈推荐它。

答案 1 :(得分:0)

_mutArray是iVar,self.mutArray通过@synthesize属性为您创建的getter和setter访问属性。您可以将这些getter和setter覆盖到适当的自定义内容。在您的示例中,您将属性设置为strong,这会为您的属性添加一个保留。所以self.mutarray = [[NSMutableArray alloc] init];会做这样的事情(除非你覆盖了属性的setter):

-(void)setMutarray:(NSMutableArray*)_mutArray{
    if(_mutArray != mutArray){
        [mutArray release];
        mutArray = nil;
        mutArray = [_mutArray retain];
    }
}

要将对象添加到数组中,您只想访问iVar,而不是属性,除非您在getter中执行自定义操作。例如,你的getter可能是这样的:

-(NSMutableArray*)mutArray{
    if(!mutArray){
        self.mutArray = [[[NSMutableArray alloc] init] autorelease];
    }
    return mutArray;
}

通过这种方式,您可以确保始终有一个真正的数组来添加对象。如果是这种情况,您可能希望使用[self.mutArray addObject:object];

所以,除非你想在getter或setter中做一些自定义的事情,否则你只想访问iVar。

答案 2 :(得分:0)

self keywordthis中的keyword JAVA类似。

它访问当前对象,它也是指向对象的指针。

for more info about self read this tutorial

_ObjeNameiVar

中被称为Objective c

实现中声明的实例变量被隐式隐藏(有效私有)并且无法更改可见性- @public, @protected and @private不会产生编译器错误(当前Clang至少< / em>)但被忽略了。

例如:

之间的差异

1) NSString *someString = _name;

2) NSString * someString = self.name;

假设你的.m文件中有这一行(并且没有任何覆盖方法来直接访问_name)

@synthesize name = _name;

这意味着当您尝试访问它时,属性name(self.name)将使用变量_name。在这种情况下,self.name等于_name


但是如果你有名字的动态属性,就像这样:

-(NSString)name{
    return @"1234";
}

然后有区别。 self.name将始终返回1234,但_name可能不等于此值。

示例:

_name = @"555";
NSLog(_name);
NSLog(self.name);

结果:

2012-02-09 14:27:49.931 ExampleApp[803:207] 555
2012-02-09 14:27:49.933 ExampleApp[803:207] 1234

Above Example I Got From this Question.