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 *rev= [str reverseString];
Categories还可以用来定义类的私有方法,一般声明和定义都放在.m文件中,方法类似。
Categories可以实现重载 :
如下重载 UINavigationBar的drawRect,可以在这个函数中绘制(如自定义背景图片),那么全局所有UINavigationBar的实例都具有自定义的样式
- (void) drawRect: (CGRect)rect
{
}
@end
2、Protocol(协议)
协议是类与类之间进行通讯的所制定一个准则。oc和java一样 都是单继承,不支持多重继承,但是可以通过协议来模拟这一机制。
协议只负责函数的声明,而具体的实现放到子类中
ESRenderer.h
- (void)render;
- (BOOL)resizeFromLayer:(CAEAGLLayer*)layer;
@end
ES1Render.h
{
}
- (void) render;
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer;
@end
}
- (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,实例 化时采用同一个 指针id< ESRenderer >render指向不同的对象。
3、delegate(代理)
代理就时由某个对象指定的另一个对象,用于执行 双方之间的协议。协议列举了代理需要处理的所有的事情,如果这些事情发生了,就发送消息给代理。
@optional
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
@end
如UIScrollViewDelegate 的- (void)scrollViewDidScroll:(UIScrollView *)scrollView; 当ScrollView滚动的时候,会交由代理去处理, 那么你就可以在代理类中重写这个函数,@optional表示代理可以处理或者不处理这个消息,那ScrollView如何知道那一个对象才是它的代理呢?
仔细看 UIScrollView类,其中包含了id<UIScrollViewDelegate> delegate; 所以在创建ScrollView的时候只需要调用ScrollView.delegate = object,object就是代理。