美文网首页
Method Swizzle

Method Swizzle

作者: ShawnDu | 来源:发表于2016-01-28 19:58 被阅读201次

    在Swift中也可以用Objective-C运行时来进行Swizzle, 如果想在一个app中监听所有的点击事件,可以这样来做:

    extension UIButton {
        class func SSSwizzleSendAction() {
            struct SSSwizzleToken {
                static var onceToken : dispatch_once_t = 0
            }
            dispatch_once(&SSSwizzleToken.onceToken) {
                let cls: AnyClass! = UIButton.self
                
                let originalSelector = Selector("sendAction:to:forEvent:")
                let swizzledSelector = Selector("SSSendAction:to:forEvent:")
                
                let originalMethod =
                class_getInstanceMethod(cls, originalSelector)
                let swizzledMethod =
                class_getInstanceMethod(cls, swizzledSelector)
                
                method_exchangeImplementations(originalMethod, swizzledMethod)
            }
        }
        
        public func SSSendAction(action: Selector,
            to: AnyObject!,
            forEvent: UIEvent!)
        {
            struct SSButtonTapCounter {
                static var count: Int = 0
            }
            
            SSButtonTapCounter.count += 1
            print(SSButtonTapCounter.count)
            SSSendAction(action, to: to, forEvent: forEvent)
        }
    }
    

    sendAction:to:forEvent:为被替换的方法,SSSendAction:to:forEvent:为替换后的方法,在运行时,对这两个方法进行了交换,在SSSendAction:to:forEvent:中调用了自己,但是因为交换了两个方法的实现,在调用时就会调用原来的方法。

    需要app启动时调用这个SSSendAction:to:forEvent:方法,可以写在UIButton初始化时调用:

    extension UIButton {
        override public class func initialize() {
            if self != UIButton.self {
                return
            }
            UIButton.SSSwizzleSendAction()
        }
    }
    

    如果Swizzle的是Swift类型的方法,需要将原方法和替换方法加dynamic标记,指明需要动态派发机制。

    相关文章

      网友评论

          本文标题:Method Swizzle

          本文链接:https://www.haomeiwen.com/subject/azrjkttx.html