objectivec基础知识(-)Categories、Protocol、delegate

1、Categories

OC中提供了 Categories机制来实现类的扩展,你可以在Categorie中添加方法,这些方法就可以被对象调用。相比普通的继承,更加方便,不需要重新定义类,添加的方法可以通过现有类的实例直接调用。总之一句话,如果你给NSString这个类添加了方法,那么NSString 所有的实例都可以调用这些方法。定义 ClassToAddMethodsTo Categories和给一类定义interface是一样的,只不过有一点区别:你需要在interace后面注明Categories的自定义名称,具体的格式如下:

@interface NSString(addition) - (NSString *)reverseString; @end
@implementation实现部分
-(NSString *) reverseString {     NSMutableString *reversedStr;     int len = [self length];     // Auto released string     reversedStr = [NSMutableString stringWithCapacity:len];          // Probably woefully inefficient...     while (len > 0)     {          [reversedStr appendString:         [NSString stringWithFormat:@"%C", [self characterAtIndex:--len]]];     }     return reversedStr; }

 接下来就是如何调用:

NSString *str  = [NSString stringWithString:@"Fubar"];
NSString *rev= [str reverseString];

Categories还可以用来定义类的私有方法,一般声明和定义都放在.m文件中,方法类似。

Categories可以实现重载 :

如下重载 UINavigationBar的drawRect,可以在这个函数中绘制(如自定义背景图片),那么全局所有UINavigationBar的实例都具有自定义的样式

@implementation UINavigationBar (CustomImage)
- (void) drawRect: (CGRect)rect
{
}
@end  

 2、Protocol(协议)

协议是类与类之间进行通讯的所制定一个准则。oc和java一样 都是单继承,不支持多重继承,但是可以通过协议来模拟这一机制。

协议只负责函数的声明,而具体的实现放到子类中 

ESRenderer.h 

@protocol ESRenderer <NSObject>
- (void)render;
- (BOOL)resizeFromLayer:(CAEAGLLayer*)layer;

@end  

ES1Render.h

@interface ES1Renderer : NSObject <ESRenderer>
{
}

- (void) render;
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer;
@end 


 @interface ES2Renderer : NSObject <ESRenderer>{
}

- (void) render;
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer;
@end  

所有遵循遵循ESRenderer协议的类(如ES1Renderer)都可以调用协议的方法,

实例化:

id< ESRenderer >render;

renderer = [[ES2Renderer alloc] init];


if (!renderer)

{ 

    renderer = [[ES1Renderer alloc] init];

    

    if (!renderer)

    {

        [self release];

 

    }

}

如代码所示:ES2Render 不支持时就使用 ES1Render,实例 化时采用同一个 指针idESRenderer >render指向不同的对象。

 3、delegate(代理)

代理就时由某个对象指定的另一个对象,用于执行 双方之间的协议。协议列举了代理需要处理的所有的事情,如果这些事情发生了,就发送消息给代理。

@protocol UIScrollViewDelegate<NSObject>
@optional
- (void)scrollViewDidScroll:(UIScrollView *)scrollView; 

@end  

 如UIScrollViewDelegate 的- (void)scrollViewDidScroll:(UIScrollView *)scrollView; 当ScrollView滚动的时候,会交由代理去处理, 那么你就可以在代理类中重写这个函数,@optional表示代理可以处理或者不处理这个消息,那ScrollView如何知道那一个对象才是它的代理呢?

仔细看 UIScrollView类,其中包含了id<UIScrollViewDelegate>      delegate;  所以在创建ScrollView的时候只需要调用ScrollView.delegate = object,object就是代理。

原文地址:https://www.cnblogs.com/chenshun/p/2439842.html