一般来说, Extension 用来给 Class 增加私有属性和方法, 写在 Class 的. m 文件. 但是 Extension 不是必须要写在. m 文件, 你可以写在任何地方, 只要在 @implementation 前定义就可以. 所以我们可以利用这个特性实现属性隐藏.
Case: 模块内部需要访问某属性, 模块外需隐藏. 这种情况经常会遇到. 例如对于某一公司来讲, 每个员工都需要员工 ID 来唯一标识, 但是员工作为自然人, 在其他地方, 别人不需要知道这个 ID. 所以对于该员工的 ID, 在公司内部需要访问, 在外部需要隐藏.
定义一个 company 对象, 一个 person 对象.
- @interface Person : NSObject
- @property (nonatomic, strong) NSString *name;
- @end
- @interface Company : NSObject
- @property (nonatomic, strong) NSString *name;
- - (void)addStaff:(Person *)person;
- - (void)printAllStaffDisplayName;
- @end
公司可以增加一个自然人当自己的员工. 可以打印全部员工 ID,
- @interface Company ()
- @property (nonatomic, strong) NSMutableArray<Person *> *staffs;
- @end
- @implementation Company
- - (void)addStaff:(Person *)person {
- person.companyID = [NSString stringWithFormat:@"大汉 %ld",self.staffs.count];
- [self.staffs addObject:person];
- }
- - (void)printAllStaffDisplayName {
- for (Person *staff in self.staffs) {
- NSLog(@"name:%@ displayName:%@ \n",staff.name,staff.companyID);
- }
- }
- - (NSMutableArray<Person *> *)staffs {
- if (!_staffs) {
- _staffs = [NSMutableArray arrayWithCapacity:0];
- }
- return _staffs;
- }
- @end
可以看到在 Company 中需要访问 Person 的 companyID, 所以我们给 Person 增加一个 Extention. 写在 Company.h.
- @interface Company : NSObject
- @property (nonatomic, strong) NSString *name;
- - (void)addStaff:(Person *)person;
- - (void)printAllStaffCompanyID;
- @end
- @interface Person ()
- @property (nonatomic, strong) NSString *companyID;
- @end
这样我们就可以在模块内部增加了一个 public 属性, 而模块外部不知道有这个属性.
- Company *cisco = [Company new];
- cisco.name = @"cisco";
- Person *tao = [Person new];
- tao.name = @"涛";
- [cisco addStaff:tao];
- [cisco printAllStaffDisplayName];
关于这个特性, 可以参考 sunny 的文章:. 但是, 当你运行的时候会发现, crash 了! log 显示找不到 setCompanyID 方法, 原来我们把 extention 写在非. m 文件的时候, oc 不会帮我们自动生成 set,get 方法. 我想手动写一个 set 方法来解决这个问题, 发现如果想在 @implenmatation 写, 就必须知道他的实例变量 _companyID, 我们现在拿不到. 联想到 readOnly 属性可以使用 extention 在. m 中修改为 readWrite:
- .h
- @interface Person : NSObject
- @property (readonly, nonatomic, strong) NSString *gender;
- @end
- .m
- @interface Person ()
- @property (nonatomic, strong) NSString *gender;
- @end
- @implementation Person
- @end
那我们也可以在 Person.m 中再次申明一个 companyID 的私有属性. 这样, oc 会帮我们自动生成 set,get 方法. 试验一下, 完美!
- @interface Person ()
- @property (nonatomic, strong) NSString *companyID;
- @end
- @implementation Person
- @end
Demo 下载 https://github.com/wangdachui/ExtentionDemo
来源: https://www.cnblogs.com/6duxz/p/10840682.html