【问题标题】:Method Swizzling for UIViewUIView 的方法调配
【发布时间】:2014-05-19 20:29:37
【问题描述】:

我正在关注“This”指南。捕获UIView touchesBegan,但是当我在UIViewControllerNSLog() touchesBegan 时,它不会触发,但会以混合方法触发。有什么办法可以让两者都开火吗?

【问题讨论】:

  • 您确定需要调酒吗?在许多情况下,有更好的方法。
  • 你会建议什么方法。我的目标是能够在应用程序的开头启动一个共享实例,然后能够从视图控制器调用类似 [Track sharedInstance]monitor:(UIView*)] 的东西,这样我就可以监控何时 touchesBegan 等.
  • 另外,我不能子类化我需要跟踪的 UIView。

标签: ios objective-c uiview swizzling


【解决方案1】:

当调配方法时,您基本上是在告诉 Objective-C 运行时将其内部映射的方法 selector(如何调用它)更改为方法 实现(调用时它会做什么)。要意识到的关键是这些在 Objective-C 中实际上不是一回事(尽管我们在编码时通常不会考虑这种区别)。如果你能理解选择器映射的概念,那么理解 swizzling 就很容易了。

典型的模式是通过交换选择器将现有方法(通常是您无法控制的类)与您自己的具有相同签名的自定义方法交换它们的选择器,以便您的选择器指向现有实现并且现有选择器指向到您的实施。

完成此操作后,您实际上可以通过调用自定义方法的选择器来调用 原始 实现。

对于外部观察者来说,这似乎创建了一个重入循环:

- (void)swizzled_touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // custom logic

    [self swizzled_touchesBegan:touches withEvent:event]; // <-- this actually calls the original implementation

    // custom logic
}

...但是因为您已经交换了选择器,所以看起来递归的选择器实际上指向了原始实现。这就是为什么调用 [view touchesBegan: withEvent:] 最终会调用你的 swizzled 方法。

不错吧?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多