Method Swizzlingとは

既存のメソッドを自作のメソッドに差し替える黒魔術です。
Objective-Cで実現する方法については、こちらのページがわかりやすいです。

既存クラスのメソッドを入れ替える(Method Swizzling)

Swiftで試す

Swiftでもclass_getInstanceMethod()とmethod_exchangeImplementations()が動くので
単純に書き換えるだけで動きました。
以下は、UIViewControllerのviewDidLoadで試したコードです。
viewDidLoadのタイミングでログを吐くようにしています。

extension UIViewController {
    func loggingViewDidLoad() {
        println("\(self.dynamicType) viewDidLoad")
    }
    
    class func switchLoggingMethod () {
        let fromMethod = class_getInstanceMethod(UIViewController.self, "viewDidLoad")
        let toMethod = class_getInstanceMethod(UIViewController.self, "loggingViewDidLoad")
        method_exchangeImplementations(fromMethod, toMethod);
    }
}

ポイント

extension

Swiftにはカテゴリがないので、extensionで実現しています。やってることはObjective-Cのカテゴリと同じです。

class_getInstanceMethod

第2引数がただの文字列です。ここが一番はまりました。
ちなみにSwift1.0では以下のような書き方になるようです。

let fromMethod = class_getInstanceMethod(UIViewController.self, Selector.convertFromStringLiteral("viewDidLoad"))

すべてのクラスで使えるわけではない

これ重要。
NSObjectを継承していないクラスでは使用できません。

参考

Swift funtime

サンプルコード

haranicle/SwiftMethodSwizzling

Pocket