iOS学习系列 - 扩展机制category与associative
iOS學習系列 - 擴展機制category與associative
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://code4app.com/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的兩種擴展機制。
作者:Leepy 郵箱:sunleepy(AT)gmail.com 出處:http://liping13599168.cnblogs.com/? 本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利。
轉載于:https://www.cnblogs.com/zsw-1993/p/4879856.html
總結
以上是生活随笔為你收集整理的iOS学习系列 - 扩展机制category与associative的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FreeSql (三)实体特性
- 下一篇: 并发编程(多进程1)