zoukankan      html  css  js  c++  java
  • Objective-C 实例变量与属性的区别

      记得刚学习OC时,对实例变量和属性总是不太清楚。

      比如下面代码中在打印Person类对象的名字时,什么时候用带“_”的name,NSLog(@"%@",p1->_name);

                            什么时候用不带“_”的name,NSLog(@"%@",p1.name);

      现在回想起来也是挺有意思的过往,写下自己曾经的迷惘,纪念一下青春?。。。。

    首先,使用实例变量编写代码。以及实例变量赋值要用到getter、setter方法。

    @interface Person : NSObject
    {
      @public
      NSString *_name;                    //定义实例变量_name
    }
    -(instancetype)initWithName:(NSString *)name;  //初始化
    -(void)setName:(NSString *)name;           //setter方法
    -(NSString *)name;                   //getter方法
    @end
    @implementation Person               //实现部分
    -(instancetype)initWithName:(NSString *)name{
        if (self = [super init]) {
            _name = name;
        }
        return self;
    }
    -(void)setName:(NSString *)name{
        _name = name;
    }
    -(NSString *)name{
        return _name;
    }
    @end
    int main(int argc, const char * argv[]) {    //主函数
        Person *p1 = [[Person alloc] initWithName:@"zhangsan"];
        NSLog(@"%@",p1->_name);
        return 0;
    }

      以上代码,均使用的是实例变量。这个大家应该都明白。那么什么时候不用下划线呢?

    使用属性编写代码(请比较两者的代码量)

    首先明确两点:

    1、属性的作用是生成setter以及getter方法的实现。并且如果.h文件中未定义对应的实例变量时,系统会生成一个“_属性名”的实例变量,但是生成的实例变量的可见度是私有的private。

    2、OC中提供属性的目的:为了简化程序员的编码。

    @interface Person : NSObject
    @property(nonatomic,copy)NSString *name;    
    -(instancetype)initWithName:(NSString *)name;
    @end
    
    @implementation Person
    -(instancetype)initWithName:(NSString *)name{
        if (self = [super init]) {
            _name = name;
        }
        return self;
    }
    @end
    
    int main(int argc, const char * argv[]) {
        Person *p1 = [[Person alloc] initWithName:@"zhangsan"];
        NSLog(@"%@",p1.name);     //属性是一对getter、getter方法,点语法是属性的另一种调用格式。 
    return 0;
    }

      此时打印,虽然属性也生成了对应的实例变量,但是实例变量是私有的,所有并不能直接打印实例变量。用点语法,相当于调用了getter方法,返回值依旧是实例变量存储的值。

    因为定义属性时语义设置的关键字是copy

    setter内部实现

     - (void)setGender:(NSString *)gender {
       if (_gender != gender) {
    
           [_gender release];
    
           _gender = [gender copy];
       }
    

    }

    getter内部实现

     - (NSString *)gender {
       return  [[_gender retain] autorelease];
    

    }

      说到这里,应该能够理解属性与实例变量的区别了。

  • 相关阅读:
    STL 之 unordered_map
    vim tab和空格相互替换
    windows使用
    debugger打不开
    存储过程中执行动态Sql语句
    什么是详细设计说明书?
    C#中调用SQL存储过程(带输入输出参数的例子)
    如何解决网站在IE8下出现布局乱的情况?
    SQLServer 游标简介与使用说明
    线程池ThreadPoolExecutor参数设置
  • 原文地址:https://www.cnblogs.com/ohmg/p/5228755.html
Copyright © 2011-2022 走看看