您的位置:首页 > 移动开发 > Objective-C

OC基础回顾(十一)类别

2015-08-20 11:03 477 查看
     在编写面向对象的程序时,经常要为现有的类添加一些新的行为,通常采用创建子类的方法。不过有时候子类不方便,比如,想为NSString类添加一个新的行为,但是NSString实际上只是一个类簇的表面形式,因而为这样的类创建子类会非常困难。
利用Objective-C的动态运行时机制,可以使用类别(category)来为现有的类添加新方法。

1.创建类别

通常类别代码放在独立的文件中,以“类名称+类别名称”的风格命名。

1.1开始创建

打开项目,在导航栏中选择你想让文件出现的群组,选择File-》New-》New File选项,或者快捷键Command+N,在弹出的新文件窗口的左侧选择 iOS-》Source,在右侧选择Objective-C File图标,点击Next:



在File一栏中输入类别的名称,选择File Type为Category,在Class中选择想要添加方法的类:



1.2 @interface部分

类别的声明看起来非常像类的声明:

@interface NSString (NumberConvenience)
-(NSNumber *)lengthAsNumber;
@end//NumberConvenience


注意:

1)只要保证类别名称唯一,就可以向一个类中添加任意数量的类别。

2)可以在类别中添加属性,但是不能添加实例变量。而且,属性必须是@dynamic类别的。添加属性的好处是,你可以通过点表达式来访问setter和getter方法。

1.3 @implementation 部分

代码:
@implementation NSString (NumberConvenience)
-(NSNumber *)lengthAsNumber
{
NSUIngeter length = [self length];
return ([NSNumber numberWithUnsignedInt:length]);
}//lengthAsNumber
@end // NumberConverience


1.4 类别的缺陷

1)无法向类中添加新的实例变量,类别没有空间容纳实例变量。

2)名称冲突,也就是类别中的方法和现有的方法重名。当发生名称冲突时,类别具有更高的优先级。导致初始方法不再可用。有些编程人员会在类别方法名中添加一个前缀,以确保不会发生名称冲突。

说明:

也有一些技术可以克服类别无法增加新实例变量的局限。例如,使用全局字典来存储对象和你想要关联的额外变量之间的映射。但此时需要认真考虑一下,类别是否是完成当前任务的最佳选择。

1.5 类别的优势

     在Cocoa中,类别主要有三个用途:将类的实现代码分散到多个不同文件或框架中,创建对私有方法的前向引用,以及向对象添加非正式协议(informal protocol)。

     利用类别可以将一个类的代码,按照不同的用途,分散到多个不同的源文件中,还可以分散到多个不同的框架中。例如,虽然NSString类是在Foundation框架中声明的,但是AppKit中有一个NSString的类别,称为NSStringDrawing,该类别允许你向字符串发送绘图消息。Cocoa的设计人员通过类别使数据功能放在Foundation框架中,而绘图功能放在AppKit框架中。

1.6 类扩展

类扩展就像是没有命名的类别。

一个类MyClass类的声明:

@interface MyClass:NSObject
@property (retain, readonly) float value;
@end


类MyClass的扩展:

@interface MyClass()
@property (retain, readwrite) float value;
@end


特点:

1)类扩展不需要名字

2)可以在你的类中使用它

3)可以添加实例变量

4)可以将只读权限改成可读写的权限

5)创建数量不限

使用场景:

某些情况,我们需要声明一个@property,它对外是只读的(readonly),而对内是可读写的(readwrite),这时,可以通过扩展来实现。

2. 通过类别创建前向引用

如果其它类中的方法未实现,在你访问其它类的私有方法时编译器会报错。这时,使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告。

3.非正式协议和委托类别

3.1 委托

Cocoa中的类经常使用一种名为委托(delegate)的技术。

委托是一种对象,另一个类的对象会要求委托对象执行它的某些操作。


3.2 委托和类别

委托+类别的一种应用:创建一个非正式协议。
通过创建非正式协议,将一些方法声明为NSObject的类别,方法的实现可以发送给任何对象,无论这些对象实际上属于哪一个类。这也意味着,只要一个类添加了这个NSObject类别的头文件,这个对象就成为了一个委托对象,可以调用类别中声明的方法。
例如:
1)下面建立一个NSObject的类别:NSObject+MyDelegateMethods



2)在NSObject+MyDelegateMethods的头文件中声明一个方法:method



在implementation文件中实现这个方法:



在另一个类中使用这个NSObject类别中的方法:



3.3 响应选择器

NSObject提供了一个名为respondesToSelector:的方法,该方法询问对象以确定其是否能够响应某个特定的消息。
为了确保委托对象能否响应消息,NSObject+MyDelegateMethods需要调用respondsToSelector:@selector(method)。如果该委托对象响应给定的消息,则向该委托对象发送该消息,否则将暂时忽略该委托对象,继续正常运行。



3.4 响应器的其他应用

选择器可以被传递,可以作为方法的参数使用,甚至可以作为实例变量存储。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Objective-C 类别