为什么不要在Objective-C的分类中声明属性

属性是什么?

属性所要表达的意思是:类中有数据在支持着它。属性是用来封装数据的。

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

为什么不能在分类中声明属性?

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

比方说你实现过一个表示个人信息的类,用分类机制将其代码分段。设计一个专门处理交友事务的分类,其中所有方法都与操作某人的朋友列表有关。如果把代表朋友列表的那项属性也放到Friendship分类里面:

@interface EOCPerson (Friendship)

@property (nonatomic, strong) NSArray *friends;

-(BOOL)isFriendsWith:(EOCPerson *)person;
                      
@end

编译这段代码的时候,会发出警告,提示此分类无法合成与friends属性相关的实例变量,所以开发者需要在分类中为该属性实现存取方法。

如果开发者自己实现属性的存取方法,就会很容易出现错误的地方。比如,内存语义不一样,可变数组等问题。

并且分类的目标在于扩展类的功能,而非封装数据。

用什么方法可以解决在分类中不能合成实例变量的问题?

1、可以把存取方法声明为,也就是说,存取方法等到运行期再提供,编译器目前是看不见的。如果决定使用消息转发机制在运行期拦截方法调用,并提供其实现,那么或许可以采用这种方法。

2、关联对象能够解决在分类中不能合成实例变量的问题。比方说,我们可以在分类中用下面这段代码实现存取方法:

#import <objc/runtime.h>
  
static const char *kFriendsPropertyKey = "kFriendsPropertyKey";

@implementation EOCPerson (Friendship)

- (NSArray *) friends 
{
   return objc_getAssociatedObject(self, kFriendsPropertyKey);
}

- (void)setFriends:(NSArray *)friends
{
   objc_setAssociatedObject(self, kFriendsPropertyKey, friends, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Win_77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值