注意:以下部分为转载.
1.类目:
类目(也成类别:Category)是一种为现有类添加新方法的方式
2.类目的局限性:
1)类目无法向已有的类中添加实利变量;
2)如果类目中的方法和已有类中的方法名称冲突时,类目中的方法优先级高,发生这种情况,则已有类的原始方法永无天日,最好的办法是将自己扩展的方法和原始方法区分开来。
3.类目的作用:
• 将类的实现分散到多个不同的文件中
– 将多个类目的声明放入同一个.h文件中
– 将实现放入多个.m方法中
• 使用类目创建对私有方法的前向引用
– 就是为类创建私有方法
• 向对象添加非正式协议
– 现在逐渐被正式协议做替代
4.类目的实例:
- #import <Foundation/Foundation.h>
- @interface MyClass : NSObject
- {
- int var1;
- int var2;
- int var3;
- }
- @end
- @interface MyClass(MyClassCategory1)
- -(void) setVar1:(int) v;
- -(int) var1;
- @end
- @interface MyClass(MyClassCategory2)
- -(void) setVar2:(int) v;
- -(int) var2;
- @end
- @interface MyClass(MyClassCategory3)
- -(void) setVar3:(int) v;
- -(int) var3;
- @end
- //注意:可以将这三个类目的声明以及类的声明放到同一个.h文件中,方便导入使用
- #import “MyClass.h”
- @implementation MyClass (MyCategory1)
- -(void) setVar1 : (int) v
- {
- var1 = v;
- }
- -(int) var1
- {
- return var1;
- }
- @end
- //注意:其他两个@implementation部分放入其他单独的两个.m文件中
- #import "MyClass.h"
- @implementation MyClass
- -(NSString *)description
- {
- return [NSString stringWithFormat:@"%d,%d,%d",var1,var2,var3];
- }
- @end
- #import “MyClass.h”
- int main(int argc,const char * argv[])
- {
- @autoreleasepool{
- MyClass *mc = [[MyClass alloc]init];
- //此处mc对象可以正常调用三对儿存取方法
- //证明类目将每一部分的存取方法都已经实现
- NSLog(@”%@”,mc);
- [mc release];
- }
- }
二、类的延展(扩展 extension)
•类的延展也可以将方法变为类的私有方法
•将私有方法声明到一个匿名类目中,并且将这个匿名类目放到类的.m文件里
•然后在类的.m的@implementation部分将这个匿名类目中的私有方法进行实现
•这样的也能够写出私有方法,但是同样也可以强行在类外部调用,也会有编译器警告
•如果私有方法的声明放入一个匿名类目中,并且这个类目放入一个.h文件中
•这个.h文件可以看做私有API
•可以将私有API不公开,而只开放给许可者来调用
•然后在使用私有API时将那个.h文件导入,然后调用私有方法,编译器警告便会消失
三、类目与非正式协议
•创建一个NSObject的类目而不实现称为“创建一个非正式协议”
•因为一般情况下类都从NSObject继承,所以NSObject的类目中所声明的方法,这个类可以实现也可以不实现
•NSObject的类目中所列出的方法表示可能希望要实现的方法,如果使用可能更好的完成工作
•因为NSObject的特殊性,所以NSObject的类目声明称为非正式协议
•创建了NSObject的类目之后,类目中声明方法对于NSObject的子类来说如何检查是否实现了哪个方法
•因为可能要调用某个NSObject类目中声明的方法,在调用时需要判断是否能够响应才行,否则会造成程序崩溃
- MyClass *mc= [MyClass new];
- if([mc respondsToSelector:@selector(test)]){
- [mc test];
- }else{
- NSLog(@"未实现test方法!");
- }
四、协议
•前面提到了非正式协议,使用非正式协议时,只需要实现自己期望的方法即可
•对应的,还有一个正式协议
•正式协议也是一个方法列表,和非正式协议不同的是,
采用正式协议时需要在声明类时说明要采用的协议
•协议就是一套标准
–定义了应该实现什么,但不关心具体怎么实现
•OC的协议是由@protocol声明的一组方法列表
–要求其它的类去实现,相当于@interface部分的声明
–@required标注的方法为必须实现方法
–@optional标注的方法为可以选择实现
•协议的实现又叫采用(遵守)协议
- @protocol 协议名称
- //方法列表
- @end
- @interface ClassName : 父类名 <协议1,协议2…>
- @end
- @implementation ClassName
- //实现协议中的方法
- @end
- @protocol MyProtocol <NSObject>
- @required
- -(int) addX:(int) x andY:(int) y;
- @optional
- -(int) substructX:(int) x andY:(int) y;
- @end
- #import "MyProtocol.h"
- @interface MyClass : NSObject <MyProtocol>
- @end
- #import "MyClass.h"
- @implementation MyClass
- -(int)addX:(int)x andY:(int)y
- {
- return x + y;
- }
- @end
•声明实例变量或方法参数时可以指定协议名称
- @interface MyClass
- {
- id<MyProtocol> myVar;
- <!--EndFragment-->
- }
- @end
- -(void) methodName:(id<MyProtocol>) obj
- {
- //方法代码
- }
•可以通过对象的conformsToProtocol:@protocol(协议名)来判断是否遵循某协议
- MyClass *mc = [[MyClass alloc] init];
- BOOL flag = [mc confirmsToProtocol : @protocol(MyProtocol)];
- //如果实现了协议,flag为真,未实现为假