35
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

SwiftでMethod Swizzling

と言っても、NSObjectを継承したクラスである必要があります。なので、Viewに関しての部品では用途は多いと思います。DictionaryやArrayなどNSObjectを継承していないクラスでは、使えません。

Method Swizzlingとは

MethodAとMethodBを入れ替えることができます。Appleのフレームワークで定義されたメソッドも変更できるので強力ですが、副作用(別の場所で既存メソッドを利用しようと思ったのに、書き換えられたメソッドが実行されてしまう)にも注意する必要があります。

コードで説明

今回は、NSDictionaryを利用したケースで説明します。今回は、descriptionを実行する際に、ログを表示する例です。まず、Extensionで実行したいメソッドを書きます。返り値は自由ですが、今回は元のメソッドの返り値を返そうと思いました。

NSDictionary.swift
extension NSDictionary {
    func myDescription() -> String {
        println("MY DESCRIPTION!!")
        return myDescription()
    }
}

そして、Extensionで拡張されたNSDictionaryを生成し、メソッドを入れ替えて、descriptionを出力してみます。

Anyfile.swift
func swizzle() {
    var dict = ["This is Key.": "This is value."] as NSDictionary
    var method: Method = class_getInstanceMethod(object_getClass(dict), "description")
    var swizzledMethod: Method = class_getInstanceMethod(object_getClass(dict), "myDescription")
    method_exchangeImplementations(method, swizzledMethod)

    println(dict.description)
}

下記のようなログが出ました!

console
MY DESCRIPTION!!
{
    "This is Key." = "This is value.";
}

dictのdescriptionメソッドはprintln実行時には既にmyDescription()に切り替わっているので、このように出来たのでした。ちょっとややこしいのですが、myDescription()のブロックで実行している、myDescription()は既にdescriptionと入れ替わっているので、myDescription()myDescription()内部で実行すると、descriptionの結果が出力されます。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
35
Help us understand the problem. What are the problem?