[iOS 8] Swiftでタイマーを使った時にハマったこと

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

今回は短いTIPSです。

    override func viewDidLoad() {
        super.viewDidLoad()
        var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "show", userInfo: nil, repeats: true)
    }

    private func show() {
        println("timer")
    }
}

Swiftのアクセス修飾子であるprivateを使ったコードを書いていました。

上記はその再現コードです。viewDidLoad()内で、一秒ごとにshow()メソッドを呼び出すタイマーを実装しています。

しかし、エラーが出ます。なんということでしょう。

2014-11-26 18:57:52.752 timerExp[12282:259826] -[timerExp.ViewController show]: unrecognized selector sent to instance 0x7fe5e0474130
2014-11-26 18:57:52.765 timerExp[12282:259826] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[timerExp.ViewController show]: unrecognized selector sent to instance 0x7fe5e0474130'

unrecognized selectorと書かれています。

しかし、show()メソッドは存在します。

ここで、privateアクセス修飾子を外したり、internal にしてあげると、解決しました。

Appleのドキュメント

All entities in your code (with a few specific exceptions, as described later in this chapter) have a default access level of internal if you do not specify an explicit access level yourself. As a result, in many cases you do not need to specify an explicit access level in your code

The Swift Programming Language: Access Control

Appleのドキュメントによると、デフォルトで多くの場合そのままでOKなアクセスコントロール(internal)がされているとのこと。

Swiftのアクセス修飾子について理解するまでは、特に付けなくても良いのかもしれませんね。

参考

The Swift Programming Language: Access Control