category与associative作为objective-c的扩展机制的两个特性,category即类型,可以通过它来扩展方法;associative,可以通过它来扩展属性;在iOS开发中,可能category比较常见,相对的associative,就用的比较少,要用它必须使用<objc/runtime.h>的头文件,然后就可以自由使用objc_getAssociatedObject以及objc_setAssociatedObject,我们来看下这两个方法: OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1); OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1); 另外还有一个方法: OBJC_EXPORT void objc_removeAssociatedObjects(id object) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1); objc_getAssociatedObject、objc_setAssociatedObject、objc_removeAssociatedObjects都是Obj-c中的外联方法,object 参数作为待扩展的对象实例,key作为该对象实例的属性的键,而value就是对象实例的属性的值,policy作为关联的策略,它的枚举包括: enum { OBJC_ASSOCIATION_ASSIGN = 0, OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, OBJC_ASSOCIATION_COPY_NONATOMIC = 3, OBJC_ASSOCIATION_RETAIN = 01401, OBJC_ASSOCIATION_COPY = 01403 }; 具体我就多说了,可以看得懂的。 另外,objc_removeAssociatedObjects可以删除指定对象实例的所有扩展属性。 现在看一个简单的例子:(引用网上的例子:http:///ios/Block-UI/504fe65d6803faa33f000003 ) 这里,定义了一个"alert view"的按钮: UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [viewController.view addSubview:button]; button.frame = CGRectMake(50, 50, 100, 44); [button setTitle:@"alert view" forState:UIControlStateNormal]; 现在对UIButton通过使用category对其进行方法扩展: @implementation UIControl (BUIControl) …... - (void)handleControlEvent:(UIControlEvents)event withBlock:(void(^)(id sender))block { NSString *methodName = [UIControl eventName:event]; NSMutableDictionary *opreations = (NSMutableDictionary*)objc_getAssociatedObject(self, &OperationKey); if(opreations == nil) { opreations = [[NSMutableDictionary alloc] init]; objc_setAssociatedObject(self, &OperationKey, opreations, OBJC_ASSOCIATION_RETAIN); } [opreations setObject:block forKey:methodName]; [self addTarget:self action:NSSelectorFromString(methodName) forControlEvents:event]; } objc_getAssociatedObject,objc_setAssociatedObject进行属性扩展: OperationKey是一个字符类型,这里表示一个键,如果Opreations为空,会setAssociatedObject一个新的opreations对象到对应键的值中间。 addTarget:action:forControlEvents对于触摸事件进行目标绑定。 NSSelectorFromString(methodName) 将触发方法: -(void)UIControlEventTouchDown{[self callActionBlock:UIControlEventTouchDown];} -(void)UIControlEventTouchDownRepeat{[self callActionBlock:UIControlEventTouchDownRepeat];} -(void)UIControlEventTouchDragInside{[self callActionBlock:UIControlEventTouchDragInside];} -(void)UIControlEventTouchDragOutside{[self callActionBlock:UIControlEventTouchDragOutside];} -(void)UIControlEventTouchDragEnter{[self callActionBlock:UIControlEventTouchDragEnter];} -(void)UIControlEventTouchDragExit{[self callActionBlock:UIControlEventTouchDragExit];} -(void)UIControlEventTouchUpInside{[self callActionBlock:UIControlEventTouchUpInside];} -(void)UIControlEventTouchUpOutside{[self callActionBlock:UIControlEventTouchUpOutside];} -(void)UIControlEventTouchCancel{[self callActionBlock:UIControlEventTouchCancel];} -(void)UIControlEventValueChanged{[self callActionBlock:UIControlEventValueChanged];} -(void)UIControlEventEditingDidBegin{[self callActionBlock:UIControlEventEditingDidBegin];} -(void)UIControlEventEditingChanged{[self callActionBlock:UIControlEventEditingChanged];} -(void)UIControlEventEditingDidEnd{[self callActionBlock:UIControlEventEditingDidEnd];} -(void)UIControlEventEditingDidEndOnExit{[self callActionBlock:UIControlEventEditingDidEndOnExit];} -(void)UIControlEventAllTouchEvents{[self callActionBlock:UIControlEventAllTouchEvents];} -(void)UIControlEventAllEditingEvents{[self callActionBlock:UIControlEventAllEditingEvents];} -(void)UIControlEventApplicationReserved{[self callActionBlock:UIControlEventApplicationReserved];} -(void)UIControlEventSystemReserved{[self callActionBlock:UIControlEventSystemReserved];} -(void)UIControlEventAllEvents{[self callActionBlock:UIControlEventAllEvents];} 注意到这里会去执行callActionBlock:方法: - (void)callActionBlock:(UIControlEvents)event { NSMutableDictionary *opreations = (NSMutableDictionary*)objc_getAssociatedObject(self, &OperationKey); if(opreations == nil) return; void(^block)(id sender) = [opreations objectForKey:[UIControl eventName:event]]; if (block) block(self); } 最终会从扩展属性中得到^block,关于^block可以参考:http://blog.csdn.net/pjk1129/article/details/6577097 最后调用: [button handleControlEvent:UIControlEventTouchUpInside withBlock:^(id sender) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"alert" message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:@"other",nil]; }]; 点击按钮就会触发一个block函数。
这样就实现了objective-c的两种扩展机制。 |
|
来自: 昵称16235376 > 《RunTime》