Giter VIP home page Giter VIP logo

Comments (1)

gsdios avatar gsdios commented on July 19, 2024

开源的目的就是为了将原理和细节公之于众,供有需要的开发者鉴别甄选。这个库和aspects唯一相似之处就是基于isa指针替换的思路,代码实现和api设计迥然不同。另外,SDMagicHook也解决了aspects未能解决的KVO冲突问题,详见https://mp.weixin.qq.com/s?__biz=MzI1MzYzMjE0MQ==&mid=2247486231&idx=1&sn=1c6584e9dcc3edf71c42cf396bcab051&chksm=e9d0c0f5dea749e34bf23de8259cbc7c868d3c8a6fc56c4366412dfb03eac8f037ee1d8668a1&token=1383088962&lang=zh_CN#rd

在开源这份代码之前我并未了解和使用过aspects,发表完https://mp.weixin.qq.com/s/wxigL1Clem1dR8Nkt8LLMw 这篇技术文章之后看到有些留言提到了aspects然后我去github大概看了一下基本思路都是基于类似kvo的isa替换,但是从api设计以及实现上也有明确的区别,我们通过以下示例简要介绍下:

假设有这样一个自定义类Test,在其内部定义了一个求和的方法,接收四个int类型的参数。

@implementation Test

- (int)sumWithA:(int)a b:(int)b c:(int)c d:(int)d {
    return a + b + c + d;
}

@end

现在要求将四个参数分别平方然后再求和。

使用aspects实现如下:

Test *testObj = [Test new];
[testObj aspect_hookSelector:@selector(sumWithA:b:c:d:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info, int a, int b, int c, int d) {
    int aa = a * a;
    int bb = b * b;
    int cc = c * c;
    int dd = d * d;
    [info.originalInvocation setArgument:&aa atIndex:2];
    [info.originalInvocation setArgument:&bb atIndex:3];
    [info.originalInvocation setArgument:&cc atIndex:4];
    [info.originalInvocation setArgument:&dd atIndex:5];
} error:NULL];

int sum = [testObj sumWithA:1 b:2 c:3 d:4];
NSLog(@">>>> %d", sum); // >>>> 30

使用SDMagicHook实现如下:

Test *testObj = [Test new];
[testObj hookMethod:@selector(sumWithA:b:c:d:) impBlock:^(typeof(testObj) this, int a, int b, int c, int d) {
    __block int res;
    [this callOriginalMethodInBlock:^{
        res = [this sumWithA:a * a b:b * b c:c * c d:d * d];
    }];
    return res;
}];

int sum = [testObj sumWithA:1 b:2 c:3 d:4];
NSLog(@">>>> %d", sum); // >>>> 30

由以上demo可以看出:
1.aspects使用AspectOptions来决定自定义方法和原始方法的执行顺序;SDMagicHook使用callOriginalMethodInBlock来调用原始方法,可以将原始方法放在自定义逻辑的前、中、后任意位置执行,更加灵活方便。

2.aspects将原始方法封装在NSInvocation里面,如果想要修改sumWithA:b:c:d:的参数值需要调用setArgument:atIndex:方法来实现,api不够简洁友好;SDMagicHook只需在callOriginalMethodInBlock的block参数内部直接调用原始的sumWithA:b:c:d:方法传参即可,直观简便。

以上示例简要列举了SDMagicHook和Aspects的众多区别中的一项,欢迎仔细研究对比两个库的代码实现以及api设计再做进一步的探讨,我们欢迎任何做了充分调研对比之后的技术交流。

from sdmagichook.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.