您的位置:首页 > 编程语言

编写高质量OC代码52建议总结:26.不要在分类中设置属性

2017-03-01 16:15 573 查看
除了"class-continuation"分类之外,其他分类都无法向类中新增实例变量。因此,无法合成实现属性所需的实例变量。
 例如:专门设计一个处理交友事物的类,其中所有的方法都与操作朋友列表有关。

#import "LYKPerson.h"

@interface LYKPerson ()
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;

-(id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName;
@end

@implementation LYKPerson
-(id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName{
return nil;
}
@end

@interface LYKPerson (Friendship)
@property (nonatomic, strong) NSArray *friends;
-(BOOL)isFriendsWith:(LYKPerson *)person;
@end
//Property 'friends' requires method 'setFriends:' to be defined - use @dynamic or provide a method implementation in this category
//Property 'friends' requires method 'friends' to be defined - use @dynamic or provide a method implementation in this category
@implementation LYKPerson (Friendship)

-(BOOL)isFriendsWith:(LYKPerson *)person{
return YES;
}

@end
 如果将分类也放入Friendship,编译这段代码时,编译器报警告。

 意思是:此分类无法合成与friends属性相关的实例变量,开发者需要在分类中为该属性实现存取方法。此时可以将存取方法声明为@dynamic,等运行时再提供方法。

 

 关联对象也能够解决此问题
static const char *key = "kty";

@implementation LYKPerson (Friendship)

-(BOOL)isFriendsWith:(LYKPerson *)person{
return YES;
}

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

-(void)setFriends:(NSArray *)friends{
objc_setAssociatedObject(self,
key,
friends,
OBJC_ASSOCIATION_RETAIN);
}

@end

这样做,需要把相似的代码写好多遍,而且在内存管理语义上容易出错,这种方法并不推荐。

 还可以通过可变数组来实现friends属性所对应的实例变量,就得在设置方法中将传入的数组参数拷贝为可变版本。这种方法也容易出错。

 

 应该把所有属性都定义在主接口中,类所封装的全部数据都应该定义在主接口中。

 

 总结:

 1.把封装数据所用的全部属性都定义在主接口中

 2.在 class-continuation 分类之外的其他分类中,可以定义存取方法,但是尽量不要定义属性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐