初心者必見!Objective-CでNSTimerの使い方10選 – Japanシーモア

初心者必見!Objective-CでNSTimerの使い方10選

初心者が学ぶObjective-CとNSTimerの基本と応用Objctive-C
この記事は約31分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

Objective-CでのNSTimerの使用法について学びたい初心者の方へ、この記事ではNSTimerの基本から、その応用方法までを幅広くカバーします。

Objective-Cは長年にわたりiOSの開発で利用されてきたプログラミング言語で、その強力な機能の一つにNSTimerがあります。

NSTimerは、特定の時間が経過した後にメソッドを呼び出すスケジュール処理を行うために使用されます。

アニメーション、ポーリング、ユーザーインターフェースの更新など、さまざまな場面でその力を発揮します。

この記事を通して、10種類のNSTimerの使い方をサンプルコードと共に紹介し、それぞれのコードの意味や動作について詳細に解説していきます。

また、NSTimerを使う上での注意点やパフォーマンスへの影響、メモリリークを防ぐ方法なども取り上げます。

これらの知識を身につけることで、あなたのObjective-Cにおけるプログラミング技術をさらに深めることができるでしょう。

○Objective-Cとは

Objective-Cは、C言語をベースにSmalltalkのオブジェクト指向概念を取り入れたプログラミング言語です。

AppleがMacOSやiOSの開発に利用してきた背景もあり、iOSアプリ開発を行う上では長らく標準的な言語でした。

メッセージング構文、ダイナミックタイピング、カテゴリーなどの特徴を持ち、豊富なフレームワークと合わせて使われます。

Swiftに移行する動きが進んでいますが、既存のObjective-Cで書かれたアプリケーションが多く存在するため、今もなお学ぶ価値は大いにあります。

○プログラミング初心者がObjective-Cを学ぶ利点

初心者にとってObjective-Cを学ぶ最大の利点は、堅牢なオブジェクト指向の基礎を築けることです。

Objective-Cはオブジェクト指向の概念が非常に強く反映された言語であり、メッセージパッシングの理解など、プログラミングの基礎概念を深く掘り下げることができます。

また、広範囲にわたるAppleのAPIとの互換性や、C言語との共通性により、他の言語への移行も比較的容易になります。

さらに、実際にiOSアプリを開発しながら、プログラミングの楽しさを実感することができるでしょう。

●NSTimerとは

NSTimerは、Objective-Cにおけるタイマー機能を提供するクラスです。

このクラスを使用することにより、開発者は指定した時間が経過した後に、特定のメソッドを呼び出すといったスケジューリングを実装できます。

NSTimerは、iOSやmacOSなどAppleのオペレーティングシステム上で動作するアプリケーションでよく使用され、背景でのデータの更新、カウントダウンタイマー、ユーザーインタラクションのための遅延処理など、多岐にわたる機能を提供しています。

NSTimerの動作は、RunLoopという概念と密接に関連しています。

RunLoopは、ユーザーからの入力、タイマーのイベント、その他の種類のイベントを処理するループのことです。

NSTimerは、このRunLoopにスケジュールされ、設定された時間が経過するとイベントを発生させます。

その結果、指定されたセレクタ(メソッド)がターゲット(通常はインスタンス)に対して呼び出されます。

NSTimerを使う主な理由は、非同期的に特定の処理を遅延実行することです。

例えば、ユーザーがあるアクションを行った後に数秒後に反応させたい場合や、定期的にデータをフェッチして更新するような場合にNSTimerが活用されます。

○NSTimerの基本的な概念

NSTimerを作成する際には、主に次の要素を指定します:

  1. タイマーが発火するまでの時間(秒単位)
  2. タイマーが発火したときにメッセージを送るオブジェクト
  3. タイマーが発火したときにターゲットが実行するメソッド
  4. タイマーが保持することができるユーザー定義のデータ
  5. タイマーが一度の発火で終了するのか、繰り返し発火するのか

これらの要素を定義することで、開発者はアプリケーション内で非同期のタイミング制御を精密に行うことができます。

○NSTimerを使うメリット

NSTimerの利点は、そのシンプルさと効率性にあります。

コード内で一定間隔で繰り返し実行したい処理がある場合、NSTimerを利用すると、タイミングを管理するための複雑なロジックを自分で書く必要がなくなります。

加えて、NSTimerはRunLoopに組み込まれているため、アプリケーションのメインループに影響を与えずに、タイマーによるイベント処理が可能です。

NSTimerは、一定間隔で同じ処理を繰り返す必要がある時、あるいは一定時間後に一度だけ処理を実行したい時に特に便利です。

例えば、ユーザーがアプリ内でストップウォッチを使用しているシナリオを考えてみましょう。

NSTimerを使って、毎秒ごとに経過時間を更新し、ユーザーインターフェースに表示することが可能です。

また、NSTimerの利用はコードの読みやすさにも寄与します。

タイマーが発火すると指定されたセレクタ(メソッド)が呼ばれるため、時間に関連した処理をそのメソッド内にカプセル化することで、関心の分離が行え、メンテナンスがしやすいコードになります。

NSTimerは実行ループに組み込まれるため、イベント駆動型のプログラミングモデルに適しており、その他のイベント処理と容易に統合することができます。

NSTimerのもう一つのメリットは、そのカスタマイズ性です。

例えば、タイマーの間隔を動的に変更したり、特定のユーザー情報をNSTimerに紐づけたりすることができます。

これにより、より柔軟にアプリケーションの特定のニーズに応じた処理が可能になります。

●NSTimerの基本的な使い方

Objective-CでNSTimerを使うときは、主にタイマーを設定し、特定の間隔でメソッドを呼び出す目的で使用されます。

NSTimerはCocoaのフレームワークにおける一種のクラスであり、定期的な時間間隔でターゲットとなるオブジェクトのメソッドを呼び出す機能を提供します。

基本的な使用方法は、NSTimerクラスのscheduledTimerWithTimeInterval:target:selector:userInfo:repeats:メソッドを呼び出し、タイマーを作成してRunLoopに追加することです。

ここではまず、指定した間隔ごとにメッセージをコンソールに表示するシンプルな例から見ていきましょう。

○サンプルコード1:一定間隔で処理を行う基本的なNSTimer

ここでは、Objective-CでNSTimerを設定し、5秒ごとにコンソールにメッセージを表示する方法を示します。

この例では、NSTimerを使って特定の間隔でメソッドを繰り返し実行しています。

#import <Foundation/Foundation.h>

// タイマーが実行するメソッド
void timerMethod(NSTimer *timer) {
    NSLog(@"タイマーから呼び出されました!");
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 5秒ごとに繰り返し実行されるタイマーを設定
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                          target:[NSBlockOperation blockOperationWithBlock:^{
            timerMethod(nil);
        }]
                                                        selector:@selector(main)
                                                        userInfo:nil
                                                         repeats:YES];
        // イベントループを開始
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

このコードでは、まず5秒ごとに繰り返し実行されるタイマーをscheduledTimerWithTimeIntervalメソッドを用いて設定しています。

ターゲットとしてNSBlockOperationのブロックを渡し、ブロック内でtimerMethodメソッドを呼び出すことで、定期的にコンソールにメッセージを表示する動作をしています。

mainセレクタはNSBlockOperationのメソッドを指しており、タイマーが実行されるたびにこのブロックが実行されます。

そして[NSRunLoop currentRunLoop] runによってイベントループが開始され、プログラムが終了しないようになっています。

実行すると、コンソールには5秒ごとに「タイマーから呼び出されました!」と表示されます。

これによって、NSTimerが定期的に特定の動作を行うことを確認することができます。

○サンプルコード2:一度だけ実行されるNSTimerの設定方法

一度だけ実行されるNSTimerは、繰り返しではなく特定のタイミングで一回だけ何かの処理を行いたい場合に便利です。

repeats:パラメータをNOに設定することで、一度のみ実行されるタイマーを作成することができます。

#import <Foundation/Foundation.h>

// タイマーが一度だけ実行するメソッド
void onceTimerMethod(NSTimer *

timer) {
    NSLog(@"一度だけ実行されるタイマーから呼び出されました!");
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 5秒後に一度だけ実行されるタイマーを設定
        NSTimer *onceTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                              target:[NSBlockOperation blockOperationWithBlock:^{
            onceTimerMethod(nil);
        }]
                                                            selector:@selector(main)
                                                            userInfo:nil
                                                             repeats:NO];
        // イベントループを開始
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

このサンプルコード2では、一度だけ実行されるタイマーを作成しています。

repeats:パラメータにNOを指定することで、設定した5秒後にonceTimerMethodメソッドが一度だけ実行されます。

その後、タイマーは自動的に無効になります。

実行すると、5秒後にコンソールに「一度だけ実行されるタイマーから呼び出されました!」と表示され、それ以上は何も起こりません。

これによって、NSTimerを一回限りのトリガーとして利用することができます。

●NSTimerの詳細な対処法

NSTimerはObjective-Cにおけるタイマー機能の実装に不可欠なクラスですが、その使用法には注意が必要です。

NSTimerを用いた処理では、実行タイミングの精度、メモリ管理、ループとの連携など、複数の要素を考慮する必要があります。

特に、タイマーが意図した通りに動作しない場合やメモリリークを引き起こさないようにするための対処法を理解することが重要です。

○サンプルコード3:NSTimerが正しく動作しないときのチェックポイント

NSTimerが予定通りに動作しない場合、いくつかのポイントをチェックすることが効果的です。

例えば、タイマーがメインスレッドに関連付けられているか、適切なRunLoopモードで動作しているかなど、潜在的な問題点を解消するためには次のようなコードを検討します。

#import <Foundation/Foundation.h>

void timerMethod(NSTimer *timer) {
    NSLog(@"タイマーから呼び出されたメソッド");
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSTimer *myTimer = [NSTimer timerWithTimeInterval:1.0
                                                   target:self
                                                 selector:@selector(timerMethod:)
                                                 userInfo:nil
                                                  repeats:YES];
        // カレントRunLoopにタイマーを追加
        [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
        // 30秒間イベントループを実行
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:30]];
    }
    return 0;
}

上記のコードでは、1秒間隔でtimerMethodメソッドを呼び出すタイマーを設定しています。

タイマーはメインスレッドのRunLoopに追加され、デフォルトモードで動作するように設定されています。

プログラムは30秒間動作し、それによりタイマーは30回のメソッド呼び出しを試みます。

このコードを実行すると、コンソールには30秒間毎秒「タイマーから呼び出されたメソッド」と表示されるはずです。

○サンプルコード4:メモリリークを防ぐためのNSTimerの扱い方

NSTimerを使用する際には、メモリリークを避けるためにタイマーを適切に管理することが求められます。

タイマーが不要になった場合や、ターゲットオブジェクトが解放される前に、タイマーを無効化する必要があります。

下記のコードは、NSTimerを無効にしてメモリリークを防ぐ方法を表しています。

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
@property (strong, nonatomic) NSTimer *myTimer;
@property (assign, nonatomic) int count;
@end

@implementation MyClass
- (void)startTimer {
    self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                    target:self
                                                  selector:@selector(timerFired:)
                                                  userInfo:nil
                                                   repeats:YES];
}

- (void)timerFired:(NSTimer *)timer {
    self.count++;
    NSLog(@"タイマー実行回数: %d", self.count);
    
    // 10回実行したらタイマーを無効にする
    if (self.count >= 10) {
        [self.myTimer invalidate];
        self.myTimer = nil;
    }
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *myInstance = [[MyClass alloc] init];
        [myInstance startTimer];
        // 15秒間イベントループを実行
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:15]];
    }
    return 0;
}

このコードでは、MyClassのインスタンスがNSTimerを作成し、毎秒timerFired:メソッドを呼び出します。

カウンターが10に達すると、タイマーを無効にしています。

これにより、タイマーによってMyClassのインスタンスが保持され続けることを防ぎます。

●NSTimerの応用例

Objective-CにおけるNSTimerは、時間経過に応じた処理を実行するために広く利用されるクラスです。

応用例としては、アプリケーションでのカウントダウンタイマーの実装、アニメーションのフレーム更新、ユーザーインタラクションに基づいた処理など、多岐にわたります。

ここではNSTimerを使用して、ユーザーインタラクションに基づいたタイマーの制御をする例と、バックグラウンド処理でタイマーを動かす2つのサンプルコードを詳細に解説します。

○サンプルコード5:ユーザーインタラクションに応じたタイマーの制御

下記のサンプルコードは、ユーザーがボタンを押すことでタイマーを開始し、再度ボタンを押すと停止する、という一連の流れを作成する方法を表しています。

// MyClass.h
#import <Foundation/Foundation.h>

@interface MyClass : NSObject
@property (strong, nonatomic) NSTimer *myTimer;
@property (assign, nonatomic) NSInteger count;
- (void)startStopTimer;
@end

// MyClass.m
#import "MyClass.h"

@implementation MyClass

- (instancetype)init {
    self = [super init];
    if (self) {
        self.count = 0;
    }
    return self;
}

- (void)startStopTimer {
    if (self.myTimer == nil) {
        // タイマーを開始
        self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                        target:self
                                                      selector:@selector(timerFired:)
                                                      userInfo:nil
                                                       repeats:YES];
    } else {
        // タイマーを停止
        [self.myTimer invalidate];
        self.myTimer = nil;
    }
}

- (void)timerFired:(NSTimer *)timer {
    self.count++;
    NSLog(@"Timer fired %ld times", (long)self.count);
}
@end

このコードではMyClassクラスが定義されており、startStopTimerメソッドによってタイマーの開始と停止が切り替わります。

タイマーが起動していない場合はstartStopTimerが呼ばれるとタイマーを開始し、すでに起動している場合はタイマーを停止します。

timerFired:メソッドはタイマーが発火するたびに呼ばれ、countプロパティをインクリメントしてログに記録します。

実行結果としては、ユーザーがボタンを一度押すとコンソールには毎秒「Timer fired 1 times」といった形でカウントが1から始まって記録されます。

もう一度ボタンを押すとタイマーが停止し、ログの記録も止まります。

○サンプルコード6:背景でタイマーを動かす方法

アプリケーションがバックグラウンドにある間にタイマーを動かし続けるには、いくつかの制限があります。

iOSはバックグラウンドタスクに対して厳しい制限を設けていますが、限られた時間、タイマーを動かすことは可能です。

// AppDelegate.m
#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidEnterBackground:(UIApplication *)application {
    UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    // バックグラウンドでタイマーを

動かす
    NSTimer *backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                                target:self
                                                              selector:@selector(timerFired:)
                                                              userInfo:nil
                                                               repeats:YES];
    // ランループに追加
    [[NSRunLoop currentRunLoop] addTimer:backgroundTimer forMode:NSRunLoopCommonModes];
}

- (void)timerFired:(NSTimer *)timer {
    NSLog(@"Timer fired in background");
    // ここで必要な処理を行う
}
@end

このコードはAppDelegateapplicationDidEnterBackground:メソッドに実装されています。

アプリケーションがバックグラウンドに入ると、バックグラウンドタスクを開始し、beginBackgroundTaskWithExpirationHandler:を使用してiOSによって終了される前に終了処理を行う機会を提供します。

バックグラウンドタイマーはNSTimerを使用して作成され、NSRunLoopに追加されます。

これにより、アプリケーションがバックグラウンドにある間もタイマーが動作し続けますが、利用可能なバックグラウンド時間は制限されており、システムによってはすぐにタイマーが停止する可能性があります。

バックグラウンドで長時間タイマーを動かす必要がある場合は、バックグラウンドフェッチやプッシュ通知など、他のAPIを検討する必要があります。

これらの機能は、アプリケーションが定期的に起動してタスクを実行する機会を提供するため、長期間にわたるバックグラウンド実行に適しています。

●NSTimerの注意点

NSTimerはiOSアプリケーションにおいて時間に基づくアクションをスケジューリングする際に非常に有用ですが、その利用にはいくつかの注意点があります。

NSTimerは内部で強参照を保持し、指定したターゲットオブジェクトとの間に強い循環参照を作成する可能性があるため、メモリリークを防ぐために適切な管理が必要です。

また、NSTimerが動作するスレッドを注意深く選ぶ必要があり、特にUIを更新する際にはメインスレッドで実行されることが重要です。

ここでは、NSTimerを安全に使うための具体的なコード例を通じて、これらの注意点について解説します。

○サンプルコード7:メインスレッドでのNSTimerの使用に関する注意

メインスレッドでNSTimerを使用する場合は、UIの更新を予定している場合に特に重要です。

NSTimerはデフォルトで実行されるスレッドのランループにスケジュールされるため、サブスレッドで生成したNSTimerはメインスレッドで生成したものとは異なる動作をします。

このコードではNSTimerを使ってメインスレッドでUIを定期的に更新する例を表しています。

例えば、秒を表示するタイマーを実装する場合を考えます。

// ViewController.m
#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) NSTimer *uiTimer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // メインスレッドでNSTimerをスケジュールする
    self.uiTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                    target:self
                                                  selector:@selector(updateUI:)
                                                  userInfo:nil
                                                   repeats:YES];
    // メインランループに追加
    [[NSRunLoop mainRunLoop] addTimer:self.uiTimer forMode:NSRunLoopCommonModes];
}

- (void)updateUI:(NSTimer *)timer {
    // UIの更新処理をここに書く
    self.timerLabel.text = [NSString stringWithFormat:@"%d", [self.timerLabel.text intValue] + 1];
}

- (void)dealloc {
    // タイマーを無効にして循環参照を防ぐ
    [self.uiTimer invalidate];
    self.uiTimer = nil;
}

@end

このコードでは、ViewControllerviewDidLoadメソッド内でメインスレッドのランループにNSTimerをスケジュールしています。

updateUI:メソッドはNSTimerによって毎秒呼び出され、UIの更新を行います。

タイマーが不要になった際には、deallocメソッド内でタイマーを無効にし、循環参照を防ぐためにnilを代入しています。

実行すると、タイマーは正確に1秒ごとにupdateUI:メソッドを呼び出し、ラベルのテキストを更新していきます。

この実装を通じてUIが滑らかに更新されることが期待できます。

○サンプルコード8:NSTimerを使う際のパフォーマンスへの影響

NSTimerは便利な機能を提供しますが、パフォーマンスへの影響も考慮する必要があります。

例えば、高頻度で発火するタイマーや、重い処理を行うタイマーはCPUやメモリリソースに負担をかけることがあります。

このような場合は、NSTimerの代わりにCADisplayLinkやGCDを使うなどの他の手法も検討すると良いでしょう。

NSTimerを使う際は、タイマーの発火間隔や実行するタスクの重さを適切にバランスさせることが重要です。

タイマーがトリガーするメソッドは、できるだけ軽量に保つことが求められます。

// 負荷の高いタスクを行うNSTimerの例
self.heavyTaskTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                       target:self
                                                     selector:@selector(performHeavyTask:)
                                                     userInfo:nil
                                                      repeats:YES];

- (void)performHeavyTask:(NSTimer *)timer {
    // 重い処理をここに書く
    // 例: データベースの大量のデータを処理する
}

この例では、5秒ごとに重い処理を行うタイマーをスケジュールしていますが、このような処理はメインスレッドで実行するべきではありません。

重い処理はバックグラウンドスレッドで非同期に実行するべきで、NSTimerの使用は軽量なタスクに限定するべきです。

さもなければ、アプリの応答性やパフォーマンスに悪影響を与えることになります。

●NSTimerのカスタマイズ方法

Objective-CにおけるNSTimerのカスタマイズは、アプリの機能を拡張し、よりリッチなユーザーエクスペリエンスを提供する上で重要な役割を果たします。

NSTimerはシンプルなタイマー機能を提供する一方で、さまざまなカスタマイズが可能です。

ここでは、NSTimerのインターバルを動的に変更する方法と、カスタムユーザー情報をNSTimerに組み込む方法について、サンプルコードと共に詳細に説明します。

○サンプルコード9:NSTimerのインターバルを動的に変更する

NSTimerのインターバルを動的に変更することは、リアルタイムでのユーザーのアクションやイベントに応じた動作をさせる際に有効です。

下記のサンプルコードは、NSTimerのインターバルをユーザーの操作に基づいて更新する方法を表しています。

// NSTimerのインスタンスを作成
NSTimer *dynamicTimer;
// インターバルの初期値を設定
NSTimeInterval timerInterval = 1.0;

// インターバルを更新するメソッド
- (void)updateTimerInterval:(NSTimeInterval)newInterval {
    // 既存のタイマーがあれば破棄する
    if (dynamicTimer) {
        [dynamicTimer invalidate];
        dynamicTimer = nil;
    }
    // 新しいインターバルでタイマーを作成する
    dynamicTimer = [NSTimer scheduledTimerWithTimeInterval:newInterval
                                                    target:self
                                                  selector:@selector(timerFiredMethod:)
                                                  userInfo:nil
                                                   repeats:YES];
}

// タイマーが発火した時に呼ばれるメソッド
- (void)timerFiredMethod:(NSTimer *)timer {
    // 実行したい処理をここに記述
    NSLog(@"Timer fired with interval: %f", timer.timeInterval);
}

このコードでは、updateTimerInterval:メソッドを使って、現在実行中のNSTimerのインターバルを新しい値に更新しています。

このメソッドは、新しいインターバル値を引数として受け取り、既存のタイマーが動いている場合はそれを破棄し、新たに指定されたインターバルでタイマーを再スケジュールします。

タイマーが発火するたびにtimerFiredMethod:が呼ばれ、ログに現在のインターバルが出力されます。

このコードを実行すると、指定したインターバルごとにコンソールにログが表示され、updateTimerInterval:メソッドを呼び出すことでインターバルを変更できることが確認できます。

○サンプルコード10:カスタムユーザー情報をNSTimerに組み込む方法

NSTimerを利用する際に特定のユーザー情報をタイマーのコールバックと共に扱いたいケースは少なくありません。

Objective-Cでは、NSTimerにuserInfo辞書を組み込むことでこの問題を解決できます。

下記のサンプルコードは、ユーザー情報を含むNSTimerの設定方法を表しています。

#import <Foundation/Foundation.h>

// タイマーのコールバックメソッド
void timerCallback(NSTimer *timer) {
    NSDictionary *userInfo = timer.userInfo;
    NSString *userName = userInfo[@"userName"];
    NSNumber *userAge = userInfo[@"userAge"];
    NSLog(@"ユーザー名: %@, 年齢: %@", userName, userAge);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // ユーザー情報の辞書を作成
        NSDictionary *userInfo = @{
            @"userName": @"田中太郎",
            @"userAge": @30
        };

        // userInfoを含むNSTimerを作成
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                          target:self
                                                        selector:@selector(timerCallback:)
                                                        userInfo:userInfo
                                                         repeats:YES];

        // ルンループに追加してNSTimerを開始
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

このコードでは、timerCallbackメソッドがNSTimerによって呼び出されるたびに、NSTimerのuserInfoに含まれているユーザー名と年齢をログに出力します。

userInfo辞書には任意の情報を含めることができるため、これを利用してカスタムデータをタイマーのコールバックメソッドに渡すことができます。

このコードを実行すると、NSTimerは1秒ごとにtimerCallbackメソッドを呼び出し、コンソールに次のような出力を繰り返します。

ユーザー名: 田中太郎, 年齢: 30
ユーザー名: 田中太郎, 年齢: 30
...

まとめ

Objective-CにおけるNSTimerの扱い方についての探求は、初心者プログラマーにとって重要なスキルを提供します。

本記事では、NSTimerの基本から、応用例、さらにはカスタマイズ方法まで、様々な角度からのサンプルコードを通じて解説を試みました。

これらのサンプルコードは、実際のアプリケーション開発で直面する可能性のある多くの状況を模倣しており、それぞれがObjective-Cを用いたタイマー機能の実装への理解を深めるために設計されています。

この記事を通じて、読者の皆様がObjective-CとNSTimerの概念をしっかりと理解し、自身のアプリケーションにタイマー機能を組み込むことでユーザーにとってより良い体験を提供できることを願っています。

これらのサンプルコードが、皆様のプログラミングにおいて有用なマイルストーンとなり、さらには自己のプロジェクトにおける創造的な発想の触媒となることを期待しています。