在 swizzled 方法中识别方法名称

Identifying method name inside a swizzled method

我有很多 classes 并且在 class 里面定义了很多方法。当这些方法中的每一个被调用时,我需要执行一组特定的操作。我可以在每个方法中编写一组操作。但我不想弄乱代码。所以我创建了一个助手 class,在里面我将传递一组 类 和选择器。

我已经遍历数组并使用调配技术并将每个方法的实现与帮助器 class 中定义的自定义方法交换。因此,每当上述任何 class 中的任何方法触发时,我都会调用我的自定义 swizzling 方法。

但我的问题是我无法区分哪个是原始方法触发的。基于此,一些参数将在我上面提到的自定义操作集中发生变化。

我当前的实现如下所示:

for i in 0..<classes.count {
   let eachClass:AnyClass = classes[i] as AnyClass
   let eachSelector:Selector = selectors[i] as Selector
   let swizzilableClass = MyHelper.self
   let originalMethod = class_getInstanceMethod(eachClass, eachSelector)
   let swizzledMethod = class_getInstanceMethod(swizzilableClass, #selector(MyHelper.trackMethodInvocation))

   method_exchangeImplementations(originalMethod, swizzledMethod)

}

而当前的调配方法是:

func trackMethodInvocation() -> Void {

}

因此,无论何时调用选择器数组中列出的任何方法,都会触发方法 trackMethodInvocation(),但我需要知道 trackMethodInvocation().

中的原始选择器

有什么方法可以知道哪个是swizzled方法中的原始方法。

所以我找到了一个替代解决方案。请注意 * 在进行实时实施之前,我会确保安全。不会再有任何循环。我要做的是,我将使用我的自定义方法调配 UIApplication 的 sendAction 方法。在我的自定义方法中,我将执行操作并调用原始的 sendAction 方法。所以代码现在如下所示,

    let originalClass:AnyClass = UIApplication.self
    let swizzilableClass = MyHelper.self

    let originalMethod = class_getInstanceMethod(originalClass, #selector(UIApplication.sendAction(_:to:from:for:)))
    let swizzledMethod = class_getInstanceMethod(swizzilableClass, #selector(MyHelper.trackMethodInvocation(_:to:from:for:)))
    method_exchangeImplementations(originalMethod, swizzledMethod)

我的 swizzled 方法看起来像,

func trackMethodInvocation(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Void {

}

所以在这里我将得到选择器。所以任何尝试这个的人,***请确保 swizzling UIApplication 方法的安全性。确保在 swizzled 方法中调用原始方法。目前我这样做只是为了研究目的。