• 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
    );
    


  • 相关阅读:
    2017面试记录
    Bzoj1079:[SCOI2008]着色方案
    Bzoj1046: [HAOI2007]上升序列
    Luogu1121:环状最大两段子段和
    BZOJ 4698: [SDOI2008]Sandy的卡片
    [SPOJ]DISUBSTR:Distinct Substrings&[SPOJ]SUBST1:New Distinct Substrings
    HiHocoder1419 : 后缀数组四·重复旋律4&[SPOJ]REPEATS:Repeats
    Bzoj2946:[POI2000] 最长公共子串
    HiHocoder1415 : 后缀数组三·重复旋律3 & Poj2774:Long Long Message
    POJ3261:Milk Patterns
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5027132.html
Copyright © 2020-2023  润新知