标签:
属性是封装数据的方式(参见第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分类”之外的其他分类中,可以定义存取方法,但尽量不要定义属性。
标签:
原文地址:http://www.cnblogs.com/Pikdays/p/5739795.html