美文网首页
self.操作访问和下划线访问区别

self.操作访问和下划线访问区别

作者: 26b5cc676194 | 来源:发表于2016-09-09 14:36 被阅读24次
    [self.book release]    [_book release]
    

    这俩个都能释放book这个对象但是我在对着MIT视频学习的时候遇到一个问题
    他是一个计算器的demo

    @property(nonatomic, strong)NSMutableArray*programStack;
    - (NSMutableArray*)programStack
    {
    if(_programStack ==nil) _programStack = [[NSMutableArrayalloc] init];
    return_programStack;
    }
    
    - (void)pushOperand:(double)operand
    {
    [self.programStack addObject:[NSNumbernumberWithDouble:operand]];
    // [_programStack addObject:[NSNumber numberWithDouble:operand]];
    }
    

    问题在这里(void)pushOperand
    这个代码是按下确认后label上的数字压入array。
    我用下面的下划线操作 这个array一直是null。
    这个俩个不是等效的吗....求解释


    显然是不一样的。
    主要是涉及到内存管理的问题。self.propertyName 使用self. 是对属性的访问。使用_ 是对局部变量的访问。
    所有被声明为属性的成员,在ios5 之前需要使用编译器指令@synthesize 来告诉编译器帮助生成属性的getter,setter方法。之后这个指令可以不用人为指定了,默认情况下编译器会帮我们生成。 编译器在生成getter,setter方法时是有优先级的,它首先查找当前的类中用户是否已定义属性的getter,setter方法,如果有,则编译器会跳过,不会再生成,使用用户定义的方法。 也就是说你在使用self.propertyName 时是在调用一个方法。如你上面的例子:

    Objective C code
    - (NSMutableArray*)programStack
    {
    if(_programStack ==nil) _programStack = [[NSMutableArrayalloc] init];
    return_programStack;
    }
    

    这是属性programStack的getter方法,是你定义的,上面提到编译器会跳过帮你生成getter方法,使用你自己在类中定义的。当我们使用self.programStack 来访问时这个getter方法就会被调用。
    这个方法中做了什么? 它判断局部变量_programStack 是否为空,如果为空,创建实例,并返回。也就是说我们在使用self.programStack 时能保证它有实例,不为空
    再看下面的这个方法,通过上面的说明,你应该能明白为什么使用 _programStack 来添加对象时,得到的是nil

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

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

    via@新浪微博:王星凯SoWhat

    相关文章

      网友评论

          本文标题:self.操作访问和下划线访问区别

          本文链接:https://www.haomeiwen.com/subject/dqieettx.html