(iPhone 開発 Cocoa)タイマーの使い方

バックグラウンドで定期的な処理を行いたいとき、使いたいタイマー。
iPhoneでは、簡単に使用できる。
基本は"scheduledTimerWithTimeInterval:"メソッドを使って呼び出したい関数を登録する。


HogeAppDelegate.h

#import <UIKit/UIKit.h>
#import "TimerManager.h"

@interface HogeAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
    UIWindow *window;
    UITabBarController *tabBarController;

    NSTimer* _timer;
    TimerManager* _timerManager;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

@end


HogeAppDelegate.m

#import "HogeAppDelegate.h"

@implementation HogeAppDelegate

@synthesize window;
@synthesize tabBarController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    
    [window addSubview:tabBarController.view];

    _timerManager = [[TimerManager alloc] init];
    // 関数名(timerFired)の後のコロン(:)を書き忘れないように注意!
    _timer = [NSTimer scheduledTimerWithTimeInterval:5.0f
        target:_timerManager
        selector:@selector(timerFired:)
        userInfo:nil repeats:YES];
}

- (void)dealloc {
    [_timerManager release];
    [tabBarController release];
    [window release];
    [super dealloc];
}

@end


TimerManager.h

#import <Foundation/Foundation.h>

@interface TimerManager : NSObject {
	NSInteger _stat;
}

- (void)timerFired:(NSTimer*)timer;

@end


TimerManager.m

#import "TimerManager.h"

@implementation TimerManager

- (void)timerFired:(NSTimer*)timer
{
    if(_stat == 0){
        NSLog(@"0");
        _stat = 1;
    } else {
        NSLog(@"1");
        _stat = 0;
        [timer invalidate];
    }
}

@end


基本はこのようになる。
targetをselfにすることもよくある。

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    
    [window addSubview:tabBarController.view];

    _timerManager = [[TimerManager alloc] init];
    _timer = [NSTimer scheduledTimerWithTimeInterval:5.0f
        target:self
        selector:@selector(timerFired:)
        userInfo:nil repeats:YES];
}

- (void)timerFired:(NSTimer*)timer
{
    if(_stat == 0){
        NSLog(@"0");
        _stat = 1;
    } else {
        NSLog(@"1");
        _stat = 0;
        [timer invalidate];
    }
}

こんな感じ。


Objective-Cになれていないと関数ポインタの後にコロンをつけ忘れる。

@selector(timerFired)

このようにしてしまうと、謎の例外で悩まされることになるので注意。