iOS之@private,@protected,@public,

2019-12-09  本文已影响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声明的变量 :

二、@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

在类的内部是可以调用的

三、@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)

上一篇下一篇

猜你喜欢

热点阅读