Farlanki

Objective-C之分类

字数统计: 821阅读时长: 3 min
2016/08/05 Share

Category

自从category被加入到Objective-C 2.0中以来,已经被开发者广泛应用到自己的App中.有了category我们可以为各种类添加新的方法.category的强大能力来源于运行时.

代码分散

使用category有利于将代码进行分散管理.假设我们要实现一个功能强大的类,我们很可能会把这个类的所有代码都写在一个文件里.为了防止各种功能的代码随意分布在文件中,我们应该使用category把各个功能的代码分开.但是,如果把所有的分类都写在一个文件里,情况也不会变得很好.所以,正确的做法应该是将各个分类写在不同的文件中,便于管理.

1
2
3
4
5
6
7
8
9
10
11
12
13
//MobilePhone+SMS.h
#import "MobilePhone"

@interface MobilePhone (SMS)
-(void)sendSMS(SMS *)sms;
@end

//MobilePhone+SMS.M
@implementation MobilePhone (SMS)
-(void)sendSMS(SMS *)sms{
//implemention of sendSMS:
}
@end

添加前缀

可以预见,由于可以向系统的类添加分类,那么可能有数个分类拥有相同名称的方法.而一旦出现这种情况,最终调用的方法是最后被加载的分类所实现的方法.所以,普遍做法是为分类中的所有方法添加一个前缀.

添加属性?

虽然不能使用category向类中添加实例变量,但是我们可以使用category为类添加属性.

1
2
3
4
5
//MobilePhone+sms.h
@interface MobilePhone(SMS)
@property (nonatomic,strong)SMS *sms;
-(void)sendSMS(SMS *)sms;
@end

然而,系统会发出警告,意思是无法合成与sms相关的实例变量,所以我们应该在分类中为期实现getter和setter,并且用@dynamic修饰它.至于getter和setter,可以使用关联对象实现.但是要注意使用关联对象的各种问题.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//MobilePhone+sms.m
@implementation MobilePhone(SMS)
@dynamic sms;
-(void)sendSMS(SMS *)sms{
//implemention of sendSMS
}
-(SMS*)sms{
//code of associatedObject
}
-(void)setSms:(SMS*)sms{
//code of associatedObject

}
@end

class-continuation分类

class-continuation分类又被称为扩展(extension).class-continuation和普通的分类不同,它必须被定义在那个接受此分类的主实现文件里.所以,因为没有各种系统类的实现文件,我们并不能向系统类添加这种分类.它可以向类添加实例变量和方法等.class-continuation分类和类本身是一起编译的,所以它可以添加实例变量.

隐藏细节

使用class-continuation分类,我们可以将变量和方法的声明移到类的实现文件中,从接口文件中就找不到其声明了.

改变读写属性

有些属性在接口文件中被声明为只读,但是如果在类内部需要设置该属性的值,怎么办呢?可以使用class-continuation分类扩展该属性为可读写,在类内部中就可以使用其setter方法设置其值.使用这种方法比起在类中直接设置ivar的优势在于可以触发KVO.

1
2
3
4
5
6
7
8
9
10
11
12
//MobilePhone.h
@interface MobilePhone : NSObject
@property (nonatomic,readonly) NSString *number;

-(id)initWithNumber(NSString *)number;
//.h文件中显示为readonly

//MobilePhone.m
@interface MobilePhone()
@property (nonatomic,readwrite) NSString *number;//.m 文件中显示为readwrite
@end
//...

参考资料:

CATALOG
  1. 1. Category
    1. 1.1. 代码分散
    2. 1.2. 添加前缀
    3. 1.3. 添加属性?
  2. 2. class-continuation分类
    1. 2.1. 隐藏细节
    2. 2.2. 改变读写属性