Aspects swift 源代码分析

本文深入分析了 Swift Aspects 库的源代码实现,探讨了方法在不同时机执行的原理,包括利用方法转发流程、自定义函数执行以及如何执行 hook 的 block。同时,介绍了 Swift Aspects 的主要流程,如动态创建子类、方法交换等,并指出了其在 Swift 中的局限性和与 Objective-C 版本的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

steipete/Aspects

的设计,挺高深莫测的

  • 一般我们 hook, hook 一个类的所有实例的方法

这里 hook 的粒度,到了对象级别

  • 而且不需要建立,大量的 IMP

利用到了固有的方法转发的流程

本文主要参考 woshiccm/Aspect

分析下 Aspects 的 swift 源代码实现

Aspects 的大概设计

1, 方法换一个时机执行

1.1, 方法转发的流程

方法执行的时候,将 hook 的 selector 的实现 IMP 替换为 _objc_msgForward 或者_objc_msgForward_stret

此时调用 selector, 就会进行消息转发

1.2,实际做事情的函数

forwardInvocation 的实现, 替换为自定义的函数

__ASPECTS_ARE_BEING_CALLED__

并添加 __aspects_forwardInvocation 的实现为 forwardInvocation 原来的实现。

我们 hook 的方法 selector ,需要进行消息转发

我们 hook 的方法 selector, 都会执行自定义的函数

__ASPECTS_ARE_BEING_CALLED__

1.3, 自定义的函数中

执行了原来的方法,和 hook 的 block

这样,原来的方法,还是跑了,但是在一个不同的时机

方便我们处理

2, 需要执行的 hook 方法

得到了有利的时机

把 hook 在前面,在后面,用来替换的方法,给执行了

2.1, 执行对应的 block

Aspects 中,把 hook 的 block 的描述信息中,捞出 NSMethodSignature

使用 NSMethodSignature,执行 hook 的 block

2.2,执行原来的方法

NSInvocation 的实例, invoke

Swift Aspect 中的具体实现

3.1 调用

有这么个实例方法

    @objc dynamic func test(id: Int, name: String) {
        print("come on")
    }

hook 上面那个方法

        _ = try? hook(selector: #selector(ViewController.test(id:name:)), strategy: .before) { (_, id: Int, name: String) in
            print("done")
        }

开始 hook


@discardableResult
    func hook<Arg1, Arg2>(
        selector: Selector,
        strategy: AspectStrategy = .before,
        block: @escaping(AspectInfo, Arg1, Arg2) -> Void) throws -> AspectToken
    {
    
        // 拿到需要插入执行的 block
        let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in
            guard aspectInfo.arguments.count == 2,
                let arg1 = aspectInfo.arguments[0] as? Arg1,
                let arg2 = aspectInfo.arguments[1] as? Arg2 else { return }
            block(aspectInfo
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值