self和下划线的区别

        主要是涉及到内存管理的问题。self.propertyName 使用self. 是对属性的访问。使用_ 是对局部变量的访问。
ios

全部被声明为属性的成员,在ios5 以前须要使用编译器指令@synthesize 来告诉编译器帮助生成属性的getter,setter方法。以后这个指令能够不用人为指定了,默认状况下编译器会帮咱们生成。 编译器在生成getter,setter方法时是有优先级的,它首先查找当前的类中用户是否已定义属性的getter,setter方法,若是有,则编译器会跳过,不会再生成,使用用户定义的方法。 也就是说你在使用self.propertyName 时是在调用一个方法。如你上面的例子:编码

- (NSMutableArray *)programStack
{
    if (_programStack == nil) _programStack = [[NSMutableArray alloc] init];
    return _programStack;
}

    这是属性programStack的getter方法,是你定义的,上面提到编译器会跳过帮你生成getter方法,使用你本身在类中定义的。当咱们使用self.programStack 来访问时这个getter方法就会被调用。
spa

这个方法中作了什么? 它判断局部变量_programStack 是否为空,若是为空,建立实例,并返回。也就是说咱们在使用self.programStack 时能保证它有实例,不为空再看下面的这个方法,经过上面的说明,你应该能明白为何使用 _programStack 来添加对象时,获得的是nil.code

- (void)pushOperand:(double)operand
{
    [self.programStack addObject:[NSNumber numberWithDouble:operand]];
   // [_programStack addObject:[NSNumber numberWithDouble:operand]];
}

    那是由于_programStack 局部变量自己指向的就是一个空对象nil. 而使用self.programStack 时,会调用上面的programStack方法,在这个方法中将_programStack指向了一个已实例的对象。orm


总结:1,self.是对属性的访问,使用它的时候编译器会判断_是否为空,为空的话自动实例化。会自动访问get和set方法对象

         2,_是对实例变量的访问,咱们没有实例化它,不能使用
内存

         3,对类里局部变量访问使用_,外部变量则用self.
get

         4,在getter方法中,不要再使用self。不然会重复调用getter方法,形成死循环编译器


注意事项:it

手动管理内存的状况下:

使用“.”语法来初始化变量的时候,会产生内存泄漏的问题:

self.nameArray = [NSMutaleArray alloc] init];

上述代码,形成的问题是,在self.nameArray的时候至关于调用了set方法,引用计数+1,后面alloc的时候,引用计数再次+1。
在咱们最后dealloc中release的时候,引用计数只减了一次,并无完成所有释放,这样就形成了内存泄漏的问题。

解决方法:就是用“_”来初始化以及访问变量,这样就不会产生内存问题,虽不是什么高明的办法,但的确有效。

_nameArray = [NSMutaleArray alloc] init];

上述即是“.”和“_”在使用的时候的简单区别。

若是是在ARC(自动管理内存)的状况下虽然不存在上述问题,但从编码规范来考虑,仍是注意点儿的好。

相关文章
相关标签/搜索