読者です 読者をやめる 読者になる 読者になる

swift:PlaygroundでNSTimerを実行する

概要

uikit - Using NSTimer in swift playground - Stack Overflowによると、playgroundでNSTimerを実行する方法は二つあります。一つは、「XCPlaygroundPageを使う」方法、もう一つは、「CFRunLoopRunを使う」方法です。

二つの方法を実際に試してみました。

OS: MacOSX El Capitan, Xcode 7.2で動作確認しました。

実装

まず、タイマー実行用に、NSTimerから派生したクラスを作成します。

このクラスは、1秒ごとに現在時刻をコンソールに表示します。

このコードをXCodeで実行すると、コンソールには一度しか表示されません。XCodeの実行プロセスが終了するためです。スレッド実行するためには、実行プロセスを終了させないようにする必要があります。

class MyTimer: NSTimer {
    func startTimer() {
        NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("onTimer"), userInfo: nil, repeats: true)
        
    }
    func onTimer() {
        let today = NSDate()
        print("現在時刻は \(today) です")
    }
}

var myTimer = MyTimer()
myTimer.startTimer()

XCPlaygroundPageを使う

XCPlaygroundPageは、Xcodeからplaygroundを使うためのモジュールです。playground要素のキャプチャ・表示、Live Viewの管理、コード実行機能を持ちます。

Xcodeは、デフォルトで、すべてのtop-levelコードを実行すると終了します。非同期処理を実行する時には、無限実行を有効にすることによってplyagroundのtop-level codeの終わりに達した後も処理を継続することを許可します。

タイマーを使うためには、無限実行フラグ(needsIndefiniteExecution)をtrueに設定します。

import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

ソースコード

import Foundation
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
class MyTimer: NSTimer {
    func startTimer() {
        NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("onTimer"), userInfo: nil, repeats: true)
        
    }
    func onTimer() {
        let today = NSDate()
        print("現在時刻は \(today) です")
    }
}

var myTimer = MyTimer()
myTimer.startTimer()

CFRunLoopを使う

CFRunLoopは、スレッドに一つ存在し、入力ソースを監視するモジュールです。

CFRunLoopRun()は、現在のスレッドのCFRunLoopオブジェクトを無限に実行します。

ソースコード

import Foundation
import XCPlayground
class MyTimer: NSTimer {
    func startTimer() {
        NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("onTimer"), userInfo: nil, repeats: true)
        
    }
    func onTimer() {
        let today = NSDate()
        print("現在時刻は \(today) です")
    }
}

var myTimer = MyTimer()
myTimer.startTimer()

CFRunLoopRun()

参考資料