6167


次のように start でコールバック関数を渡して、処理が終わったらコールバック関数を実行したいです。

[code]

    func callAPI() {
        SomeAPI().start(someAPICompleted)
    }
    
    func someAPICompleted(api: SomeAPI) {
        // SomeAPI終了時の処理
    }
    
[/code]

上記の SomeAPI のようなクラスを複数作りたいので、共通処理は親クラスの AbstractAPI に書いています。

[code]

    class AbstractAPI {
    
        var caller: (()->())?
    
        init() {}
    
        func start<T: AbstractAPI>(callBack:(T)->()) {
            caller = {[unowned self]()->() in 
                callBack(self as T)
            }
            // 処理開始...
        }
    
        // 処理完了後に呼ばれる
        func completed() {
            caller?()
        }
    }
    
[/code]

completed() でコールバックを実行しなければいけないので、start
でコールバックをインスタンス変数に入れようと思ったんですが、変数の型をどうすればいいか分からず上記のようにクロージャーで包んで保持しています。

しかしこの書き方は冗長なので、できれば改めたいです。

最初Any型の変数にコールバック関数を保持しようと思ったんですが、Any型の変数を()で実行するとコンパイルエラーになりました。

[code]

    let f: Any = {println("Hello")}
    f()
    
[/code]

※f()でコンパイルエラーになる

もう少しスマートなやり方はないでしょうか？


CC BY-SA 3.0
2015-02-08T14:51:29.977
6156
2015-03-01T01:59:08.237
2015-03-01T01:59:08.237
8148
8148
question
swift
引数型の不定な関数を変数にいれたい


引数型の不定な関数を変数に入れたいというのが、一引数で型がわからないというのであれば  
引数に `Any` を受け取る変数 `var caller:((Any)->())?` を使用すればよいと思います。

以下サンプルとなります。

[code]

    class AbstractAPI {
        var caller:((Any)->())?
    
        func start(callBack:(Any)->()) {
            caller = callBack
            // 処理開始...
            completed()
        }
    
        // 処理完了後に呼ばれる
        func completed() {
            caller?(self)
        }
    }
    
    class SomeAPI : AbstractAPI {
        func callAPI() {
            self.start(someAPICompleted)
        }
    
        func someAPICompleted(api: Any) {
            if let obj = api as? SomeAPI {
                println(obj)
            }
        }
    }
    
[/code]

そうではなく、引数の数及び型が不定な場合は最初のように引数なしの関数で包むのがよいのではと思います

`Any` では制約が弱いと感じる場合は以下のようにすれば多少制限をかけられるかもしれません。

[code]

    class API {}
    
    class AbstractAPI<T:API> : API{
        var caller:((T)->())?
    
        func start(callBack:(T)->()) {
            caller = callBack
            // 処理開始...
            completed()
        }
    
        // 処理完了後に呼ばれる
        func completed() {
            caller?(self as T)
        }
    }
    
    class SomeAPI<T:API> : AbstractAPI<T> {
        func callAPI() {
            start(someAPICompleted)
        }
    
        func someAPICompleted(api: T) {
            if let obj = api as? SomeAPI {
                println(obj)
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2015-02-09T01:34:57.500
6167
2015-02-09T01:34:57.500
5106
6156
answer