除了扩展之外,其他类别都无法向类中新增实例变量,所以,编译器无法把实现属性所需的实例变量合成出来。
从概念上讲,属性是封装数据的方式。类别是扩展类功能的手段,而非封装数据。因此,一般情况下应该避免把属性声明在类别中,而应该声明在“主接口”中。
如果不得不这么做的话,可以使用关联对象辅助实现:
//// NimoPerson+Friendship.h// PersonDemo//// Created by Tony on 15/8/17.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#import "NimoPerson.h"@interface NimoPerson (Friendship)@property (nonatomic, strong) NSArray *friendsArray;@end
//// NimoPerson+Friendship.m// PersonDemo//// Created by Tony on 15/8/17.// Copyright (c) 2015年 NimoWorks. All rights reserved.//#import "NimoPerson+Friendship.h"#importstatic const char *kFriendsPropertyKey = "kFriendsPropertyKey";@implementation NimoPerson (Friendship)- (NSArray *)friendsArray { return objc_getAssociatedObject(self, kFriendsPropertyKey);}- (void)setFriendsArray:(NSArray *)friendsArray{ objc_setAssociatedObject(self, kFriendsPropertyKey, friendsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end
需要特别留意的是设置方法中的内存管理语义:
关联类型 | 等效的@property属性 |
OBJC_ASSOCIATION_ASSIGN | assign |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | nonatomic, retain |
OBJC_ASSOCIATION_COPY_NONATOMIC | nonatomic, copy |
OBJC_ASSOCIATION_RETAIN | retain |
OBJC_ASSOCIATION_COPY | copy |