博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第26条:勿在分类中声明属性
阅读量:6922 次
发布时间:2019-06-27

本文共 1015 字,大约阅读时间需要 3 分钟。

属性是封装数据的方式(参见第6条)。

属性只是定义实例变量及相关存取方法所用的“语法糖”,所以也应遵循同实例变量一样的规则。

 

 

 

分类机制,应该将其理解为一种手段,目标在于扩展类的功能,而非封装数据。

 

 

尽管从技术上说,分类里也可以声明属性,但这种做法应该尽量避免。

原因是:除了“class-continuation分类”(参见第27条)之外,其他分类都无法向类中新增实例变量,因此,它们无法把实现属性所需的实例变量合成出来。

 

所以开发者需要在分类中为该属性实现存取方法。

1)此时可以把方法声明为@dynamic,也就是说,这些方法等到运行期再提供,编译器目前是看不见的。如果决定使用消息转发机制(参见第12条)在运行期拦截方法调用,并提供其实现,那么或许可以采用这种做法。

 

2)关联对象(参见第10条)能够解决在分类中不能合成实例变量的问题。

缺点:相似的代码要写很多遍,而且内存管理问题上容易出错。

例:

#import <objc/runtime.h>

static const char *kFriendsPropertyKey = "kFriendsPropertyKey";

@implementation Person(Friendship)

-(NSArray*)friends {

  return objc_getAssociatedObject(self, kFriendsPropertyKey);

}

-(void)setFriends:(NSArray*)friends {

  objc_setAssociaedObject(self, kFriendsPropertyKey, friends, OBJC_ASSOCIATION_NONATOMIC);

}

@end

 

3、只读属性可以在分类中使用。属性可以不需要由实例变量来实现。

由于只读属性在.m中只有一个getter方法,

即实现了该属性所需的全部方法,所以编译器不会再为属性自动合成实例变量。也就满足上面的条件了,编译器也就不会发出警告信息。

 

总结:

即便这3种方法可以实现,但不推荐。

而应该把封装数据所用的全部属性都定义在主接口里。

在“class-continuation分类”之外的其他分类中,可以定义存取方法,但尽量不要定义属性。

 

转载于:https://www.cnblogs.com/Pikdays/p/5739795.html

你可能感兴趣的文章
我的友情链接
查看>>
分组计算描述性统计量
查看>>
redhat安装ibm,rdac多路径的奇葩经历
查看>>
【Python之旅】第三篇(二):Pickle序列化
查看>>
移动端keyup事件 ios端 输入框实时变化
查看>>
CSS中选择器权重计算的例题
查看>>
yum提示another app is currently holding the yum lock
查看>>
5款靠谱的安卓备份应用
查看>>
ContentProvider+ContentResolver+ContentObserver
查看>>
ORA-28001: the password has expired解决方法
查看>>
获取不同尺寸3.5/4.0的屏幕大小和系统ios 6/7的版本
查看>>
DOM和IE获取滚动条滚动的距离
查看>>
脚本类模型(客户端网页编程)
查看>>
LVS负载均衡配置与实现
查看>>
java中常见的IO体系
查看>>
storm java 编程思路
查看>>
大数据技术创新呈现“原创-开源-产品化”的阶梯格局
查看>>
spark combineByKey
查看>>
NMath矩阵分解的两种方式
查看>>
启动AVD时log提示“emulator-X disconnected! Cancelling 'X activity launch'!”
查看>>