Objective-C基础教程八

时间:2022-09-07 08:25:50

Category为我们提供了区别于继承的另外一种方法来对类进行扩展。我们可以向任何已有的类添加成员函数来实现功能上的扩展(注:category只允许添加成员函数,不能添加数据成员),添加的函数可以访问类中所有的数据成员,该类的子类也将继承新添加的成员函数。

声明category

@interface 需要扩展的类(category名称)
//需要添加的函数
@end


实现category

@implementation 需要扩展的类(category名称)
//需要添加的函数
@end


category的局限性

1,无法向类中添加新的实例变量。2,名称冲突,即类别中的方法与现有方法重名,此时,类别方法具有更高的优先级。


category的作用

1,将类的实现分散到多个不同文件或多个不同框架中。这个是应对特别复杂的类。好多行代码放在一起看起来比较乱。

2,创建对私有方法的前向引用。

简单的说,就是创建一些个人认为的私有方法,只在category中声明。这样在@interface中不会出现其声明,在@implementation中的某些方法调用这些方法即可,这样便于组织和生成文档。

3,向对象添加非正式协议。

Cocoa中的类经常使用一种名为委托(delegate)的技术,委托是一种对象,另一个类的对象会要求委托对象执行它的某些操作。例如,当AppKit类的NSApplication启动时,它会询问其委托对象释放应该打开一个无标题窗口。

更常用的是,编写委托对象并将其提供给其他一些对象,通常是提供给Cocoa生成的对象。通过实现特定的方法,你可以控制Cocoa中的对象的行为。

所有这些委托对象与类别有什么关系呢?委托强调类别的另一种应用:被发送给委托对象的方法可以声明为一个NSObject的类别。

@interface NSObject(NSNetServiceBrowserDelegateMethods)

-(void) netServiceBrowserWillSearch:(NSNetServiceBrowser *) browser;

通过将这些方法声明为NSObject的类别,NSNetServiceBrowser的实现可以将这些消息之一发送给任何对象,无论这些对象实际上属于哪个类。这也意味着,只要对象实现了委托方法,任何类的对象都可以成为委托对象。

创建一个NSObject的类别成为“创建一个非正式协议”。非正式协议只是一种表达方式,它表示“这里有一些你可能希望实现的方法,因此你可以使用它们更好地完成工作”。


选择器

选择器只是一个方法名称,但它以Objective-C运行时使用的特殊方式编码,以快速执行查询。你可以使用@selector()预编译指令指定选择器,其中方法名称位于圆括号中。因此,Car类的setEngine:方法的选择器是:

@selector(setEngine:);

NSObject提供了一个名为respondsToSelector:的方法,该方法询问对象以确定其是否能够响应某个特定的消息。下面的代码段使用了respondsToSelector:方法:

ITunesFiner *finder = [[ITunesFinder alloc] init];
if([finder respondsToSelector:@selector(setEngines:)]){
NSLog(@"yowza!");
}


正式协议

正式协议就像Java的接口一样。事实上,Objective-C的协议正是受了Java接口的启发。和Java类似,单继承,但是可以实现多个接口。

声明协议:

@protocol NSCopying

- (id) copyWithZone: (NSZone *) zone;

@end

和@interface的声明是类似的。


采用协议

@interface Car: NSObject <NSCopying>

xxxx

@end//Car

同时实现两个协议就是

@interface Car: NSObject <NSCopying, NSCoding>


在新版本的objective-c中,增加了协议的一些可选项,@optional,@required,协议中的方法必须实现,不然会报错,但是如果以@optional修饰的话便没有这种限制,默认必须实现的方法其实就相当于以@required修饰。