美文网首页
iOS之@private,@protected,@public,

iOS之@private,@protected,@public,

作者: 枫叶无处漂泊 | 来源:发表于2019-12-09 11:40 被阅读0次

    前言

    经常开发的过程中在类中定义成员变量,声明成员变量的时候,发现可以在变量前面加上@private,@protected,@public,@package。他们之间有啥区别么?下面就说一下。

    一、@private

    代表私有,也就是只有自己有,别人谁都不可用,不可以继承的。

    让我们用代码实践一下,如下定义一个Person.h

    @interface Person : NSObject {
        
        @private
        NSString *_priName;
    }
    
    @end
    
    

    在Person.m代码如下:

    @implementation Person
    
    - (instancetype)init {
        
        self = [super init];
        if (self) {
            
            //类内部可以调用
            self->_priName = @"私有变量";
        }
        return self;
    }
    
    @end
    
    

    在类外调用这个方法:

     Person *person = [[Person alloc] init];
      //会报Instance variable '_priName' is private这个错误
     person->_priName = @"私有变量";
    
    

    在类的外部,也无法访问私有变量。
    在继承于Person的Student中

    @implementation Student
    
    - (instancetype)init {
        
        self = [super init];
        if (self) {
            
            //Instance variable '_priName' is private 编译的时候报错
            self->_priName = @"ahaha";
        }
        return self;
    }
    
    

    说明继承Person的Student也访问不了父类私有变量。

    使用@private声明的变量 :

    • @private变量只能在类内部调用,在类外无法访问
    • 继承该类的子类也无法访问

    二、@protected 受保护的

    相较上边的private而言,就没有那么自私了,它自己可以用,自己的子类也是可以共享的,是可以继承的.

    在Person.h添加@protected类型的变量

    @protected
    NSString *_proName;
    
    

    在Student.m初始化init里给这个_proName赋值

    @implementation Student
    
    - (instancetype)init {
        
        self = [super init];
        if (self) {
            
    //       self->_priName = @"ahaha";
            
            //没有报错,所以子类能访问
            self->_proName = @"受保护变量";
        }
        return self;
    }
    
    @end
    
    

    没有报错,所以子类能访问。

    Person *person = [[Person alloc] init];
    //编译报异常,Instance variable '_proName' is protected
    person->_proName = @"aaa";
    
    

    说明在类外面也不能调用@protected声明的变量

    @implementation Person
    
    - (instancetype)init {
        
        self = [super init];
        if (self) {
            
            //类内部可以调用
            self->_proNmae = @"受保护变量";
        }
        return self;
    }
    
    @end
    
    

    在类的内部是可以调用的

    • @potected可以访问的权限比private大
    • 在类外面不能调用potected变量
    • 在类里或者继承该类的子类里可以使用该变量

    三、@protected 公开的

    相较上边而言,谁都可以用,只要你有这个类的对象,就可以拿到public下的变量。

    在Person.m文件里

    //没报错
     self->_proNmae = @"公开的变量";
    
    

    可以在类实例里面调用

    在Student.m文件里

    //没报错
     _proNmae = @"公开的变量";
     
    

    在该类的子类Student实例内也可以调用

    //没报错
    self->_proNmae = @"公开的变量";
    
    

    可以在该类子类实例里面调用

    //无编译异常
    Person *person = [[Person alloc] init];
    person->_pubName = @"父类公开变量";
    
    //无编译异常   
    Student *stu = [[Student alloc] init];
    stu->_pubName = @"子类公开变量";
    
    

    说明子类和父类在类外面可以访问@public变量

    • 该类实例内,还是在外面调用都可以
    • 继承的子类的实例内或者在外面调用改实例都可以获取该变量

    四、@package 框架的

    这个主要是用于框架类,使用@private太限制,使用@protected或者@public又太开放,就使用这个package吧。

    你可以使用pods引入一个第三方框架,然后在改变第三框架的源码,可以在类中加上

    @package
    NSString *_pacName;
    
    

    然后在框架外声明实例并且访问这个变量

    
    //修改的对象例如PFObject
    PFObject *object = [[PFObject alloc] init];
    //这里不会报错提示,运行时候会报错
    object->_pacName = @"框架外赋值";
    
    

    运行时报错:

    
    Undefined symbols for architecture x86_64:
      "_OBJC_IVAR_$_DTAttributedLabel._pacName", referenced from:
          -[ViewController viewDidLoad] in ViewController.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    
    • 对于framework内部,相当于@public
    • 对于framework外部,相当于@private
      这个特性,很适合用于开发第三方的静态类库,因为多数人并不希望让别人知道自己属性的值。

    相关文章

      网友评论

          本文标题:iOS之@private,@protected,@public,

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