除了"class-continuation"分类之外,其他分类都无法向类中新增实例变量。因此,无法合成实现属性所需的实例变量。
意思是:此分类无法合成与friends属性相关的实例变量,开发者需要在分类中为该属性实现存取方法。此时可以将存取方法声明为@dynamic,等运行时再提供方法。
关联对象也能够解决此问题
这样做,需要把相似的代码写好多遍,而且在内存管理语义上容易出错,这种方法并不推荐。
还可以通过可变数组来实现friends属性所对应的实例变量,就得在设置方法中将传入的数组参数拷贝为可变版本。这种方法也容易出错。
应该把所有属性都定义在主接口中,类所封装的全部数据都应该定义在主接口中。
总结:
1.把封装数据所用的全部属性都定义在主接口中
2.在 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 分类之外的其他分类中,可以定义存取方法,但是尽量不要定义属性。