ストップウォッチアプリ02〜タイマーの基本動作の確認

ストップウォッチアプリを作るために、タイマー機能の基本動作の確認を行います。

Xcode4.4での実装方法を段階を踏んで模索していきます。
もとまかさんのページをそのまま真似てもエラーになるためです。。。

  1. startボタンを押す
    • => 0.000から0.001秒ごとにカウントアップした値を表示
  2. stopを押す
    • => stopを押したタイミングでカウントアップを止め、そのときのカウントの値を表示する
  3. clearを押す
    • => カウンターの表示を0に戻す

※stop押下後、再度startを押してそのままカウンターを再スタートさせるところまでは行いません。

まず、startを押すとカウントアップした値を順にラベルに表示する第一段階まで実装していきます。

全体的な流れ

  • 1.アプリ起動時(ロード時)にタイマーを開始★
    • 0.001秒ごとにあるOnTimer関数を呼ぶ
      • OnTimer関数の中では、グローバルなフラグ(startボタンが押されたかどうか)をチェックする。
        • TRUEであれば、ラベルを「現在時刻ーstartボタンを押した時刻」に書き換える
  1. 2.アプリ終了時(アンロード時)にタイマー終了★

ポイント

★部分です。
とくに、アプリ終了時のタイマー終了処理がないとビルドエラーになるので注意が必要です。
もとまかさんのページのソースでは、このタイマー解放が書かれてなかったのでエラーになっていたようです。

ソース

.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController{
    NSTimer *timer;
}

-(void)onTimer:(NSTimer*)timer;
- (IBAction)clear_down:(id)sender;
- (IBAction)stop_down:(id)sender;
- (IBAction)start_down:(id)sender;
@property (weak, nonatomic) IBOutlet UILabel *lbl;
@end

.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize lbl;

NSDate *stdate;
BOOL timeflg=FALSE;


- (void)viewDidLoad
{
    [super viewDidLoad];

    //「onTimerという処理を、0.001秒間隔で繰り返し実行する」
    timer = [NSTimer scheduledTimerWithTimeInterval:(0.001)
                                             target:self selector:@selector(onTimer:)
                                           userInfo:nil repeats:YES];

}

- (void)viewDidUnload
{
    [self setLbl:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    [timer invalidate];//★タイマー解放忘れずに
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (void)onTimer:(NSTimer*)timer {
    // グローバルなフラグがTRUEのとき、
    // つまり、startボタンが押されたら常に真となり下記処理が実行される
    if(timeflg){
        NSDate *now = [NSDate date];
        self.lbl.text = [NSString stringWithFormat:@"%.3f",
                         [now timeIntervalSinceDate:stdate]];
    }
}

- (IBAction)clear_down:(id)sender {
}

- (IBAction)stop_down:(id)sender {
}

- (IBAction)start_down:(id)sender {
    timeflg = TRUE;
    stdate = [NSDate date];
    //[stdate retain];// ★unavailableエラーのためコメントアウト
}
@end

疑問点

startボタン押下時の時間を保持するためのretainについてです。
もとまかさんのページでは、

3.stdateを「retain」して、継続して利用可能に。

という記述があるのですが、Xcode4.4の環境ではretainというオプションがunavailableエラーになって使えません。
コメントアウトすると動くので自動的にretain(=保持)されている?ようです。
どういう仕様変更があったのか確認しておく必要がありますが、とりあえず保留ということで。

次回

stopボタンとclearボタンを実装します。

参考

もとまかさんのページにあった、タイマー表示原理です。

1.Startボタンをタップすると「timeflg」がTrueになってカウンター始動。
2.この時の日時を「stdate」に保持する。
3.stdateを「retain」して、継続して利用可能に。★
4.onTimer内で、その時点の日付(now)を取得。
5.stdateとnowの間隔をミリ秒単位でラベルに表示する。

http://iphoneapp.gjpw.net/
が、タイマー解放について参考になりました。