iOS 在下面 AOP 程序


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] run1
2014-10-28 22:52:52.744 JoinShow[3751:79389] fun running. sum : 3
2014-10-28 22:52:52.745 JoinShow[3751:79389] run2
2014-10-28 22:52:52.745 JoinShow[3751:79389] berore fun. a = 3, b = 4
2014-10-28 22:52:52.745 JoinShow[3751:79389] fun running. sum : 7
2014-10-28 22:52:52.745 JoinShow[3751:79389] after fun. a = 3, b = 4, sum = fun running. sum : 7
2014-10-28 22:52:52.746 JoinShow[3751:79389] run3
2014-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
);



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM