標籤:
iOS 在下面 AOP 程式概念
在軟體業。AOP對於Aspect Oriented Programming縮寫,手段:面向方面的編程。它是一種函數式編程張燕生風扇類型。通過這樣一個技術方案功能的先行編譯和動態代理統一維護執行。的準系統是:錄,效能統計,安全控制。交易處理,異常處理等等。基本的意圖是:將日誌記錄,效能統計。安全控制,交易處理。異常處理等代碼從商務邏輯代碼中劃分出來,通過對這些行為的分離。我們希望能夠將它們獨立到非指導商務邏輯的方法中,進而改變這些行為的時候不影響商務邏輯的代碼。
運用
這裡舉個範例,我們有個方法sumA:andB:, 用來返回ab之和的一個字串,我們在這種方法前和方法後都添加個一段代碼
- 在執行方法前我們把參數改成2和3, 當然這裡是示範用,實際用的時候別改參數,不然其它同事真的要罵人了
- 在執行方法後我們輸出傳入的參數和返回值
- (void)clickTestAop:(id)sender{ AopTestM *test = [[AopTestM alloc] init]; NSLog(@"run1"); [test sumA:1 andB:2]; NSString *before = [XYAOP interceptClass:[AopTestM class] beforeExecutingSelector:@selector(sumA:andB:) usingBlock:^(NSInvocation *invocation) { int a = 3; int b = 4; [invocation setArgument:&a atIndex:2]; [invocation setArgument:&b atIndex:3]; NSLog(@"berore fun. a = %d, b = %d", a , b); }]; NSString *after = [XYAOP interceptClass:[AopTestM class] afterExecutingSelector:@selector(sumA:andB:) usingBlock:^(NSInvocation *invocation) { int a; int b; NSString *str; [invocation getArgument:&a atIndex:2]; [invocation getArgument:&b atIndex:3]; [invocation getReturnValue:&str]; NSLog(@"after fun. a = %d, b = %d, sum = %@", a , b, str); }]; NSLog(@"run2"); [test sumA:1 andB:2]; [XYAOP removeInterceptorWithIdentifier:before]; [XYAOP removeInterceptorWithIdentifier:after]; NSLog(@"run3"); [test sumA:1 andB:2];} - (NSString *)sumA:(int)a andB:(int)b{ int value = a + b; NSString *str = [NSString stringWithFormat:@"fun running. sum : %d", value]; NSLog(@"%@", str); return str;}
我們運行這段代碼的時候,大夥猜猜結果是啥.結果例如以下
2014-10-28 22:52:47.215 JoinShow[3751:79389] run12014-10-28 22:52:52.744 JoinShow[3751:79389] fun running. sum : 32014-10-28 22:52:52.745 JoinShow[3751:79389] run22014-10-28 22:52:52.745 JoinShow[3751:79389] berore fun. a = 3, b = 42014-10-28 22:52:52.745 JoinShow[3751:79389] fun running. sum : 72014-10-28 22:52:52.745 JoinShow[3751:79389] after fun. a = 3, b = 4, sum = fun running. sum : 72014-10-28 22:52:52.746 JoinShow[3751:79389] run32014-10-28 22:52:52.746 JoinShow[3751:79389] fun running. sum : 3
實現原理
用Objective-C強大的runtime.
我們知道當給一個對象發送一個方法的時候, 假設當前類和父類都沒實現該方法的時候就會走轉寄流程
- 動態方法解析 -> 高速訊息轉寄 -> 標準訊息轉寄
迷茫的同學請搜 "Objective-C 訊息轉寄".
瞭解了訊息轉寄,那麼我們aop的思路就來了,我們是先幹掉原本的方法funa,這樣當給對象發送方法的時候就會走轉寄流程,我們再hook了對象的高速訊息轉寄方法,把實現funa的對象指成我們的aop對象, 最後在aop對象的標準訊息轉寄裡運行before instead after方法.
詳細的代碼歡迎大夥去github下載, 記得給咱點個star
link https://github.com/uxyheaven/XYQuickDevelop
在代碼裡搜 XYAOP.h
相關一些方法介紹
介紹一些用到的runtime方法
// 給 cls 加入一個新方法BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types);// 替換 cls 裡的一個方法的實現IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types);// 返回 cls 的指定方法Method class_getInstanceMethod ( Class cls, SEL name);// 建立實施的方法IMP method_setImplementation ( Method m, IMP imp);// 返回 cls 內 name 實施IMP class_getMethodImplementation ( Class cls, SEL name);
iOS 在下面 AOP 程式