Objective-C初心者のためのNSNotificationCenter入門10選

Objective-Cプログラミングの基本を学ぶ初心者のための図解入門書Objctive-C
この記事は約18分で読めます。

 

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

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

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

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

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

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

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

はじめに

Objective-Cを学びたいと考えているあなたへ。

この記事を読むことで、AppleのiOSやOS Xのアプリケーション開発に不可欠なプログラミング言語であるObjective-Cの基本から、アプリケーション間の情報伝達を円滑にするNSNotificationCenterまでの理解が深まります。

今回は特にNSNotificationCenterを使ったサンプルコードとその解説を通じて、初心者でもObjective-Cの強力な機能を活用できるようになることを目指します。

この記事が、あなたのプログラミング学習の一助となることを願っています。

●Objective-Cとは

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

Appleによって開発されたこの言語は、長年にわたりMacとiOSのアプリケーション開発の中核を担ってきました。

その特徴は、動的なランタイムとリッチなライブラリであり、これによって開発者はパワフルかつ柔軟なソフトウェアを作成できます。

また、Objective-CはC言語との互換性を持ち、CやC++のコードと組み合わせて利用することも可能です。

これにより、さまざまなレガシーコードやライブラリを活用することができるのです。

○Objective-Cの歴史と特徴

Objective-Cは1980年代にBrad CoxとTom Loveによって開発されました。

彼らの目的は、C言語の効率的な機能にSmalltalkのオブジェクト指向プログラミング能力を組み合わせることでした。

AppleがNeXTを買収したことにより、NeXTSTEP OSの開発言語として採用され、その後Mac OS XとiOSの標準開発言語になりました。

Objective-Cの強みはその拡張性にあります。

クラスの継承、ポリモーフィズム、動的タイピングなどの概念を活用することで、柔軟なコードの記述が可能です。

○Objective-Cの基本構文

Objective-Cでのプログラミングを始めるにあたって、まずは基本的な構文に慣れることが大切です。

例えば、Objective-Cではメソッドの呼び出しをブラケット[]を使って行います。また、ヘッダ(.h)と実装(.m)ファイルを分けてクラスを定義します。

これにより、プログラムの構造が明確になり、他の開発者がコードを読みやすくなります。

さらに、Objective-Cではポインタを用いたメモリ管理が必要となり、これは初心者にとってはやや高度な概念ですが、強力なアプリケーションを作成する上で欠かせない知識です。

また、Objective-Cの特有の機能であるカテゴリやプロトコルによって、既存のクラスを拡張したり、特定のメソッドの実装を他のクラスに要求したりすることが可能になります。

これらの概念を理解することで、Objective-Cの真価を引き出すことができるようになるでしょう。

●NSNotificationCenterとは

NSNotificationCenterはObjective-Cにおける中心的な機能の一つで、アプリケーション内のさまざまなコンポーネント間で情報のブロードキャストを可能にします。

この機能を使うと、一つのイベントが発生したときに複数の箇所に通知を送り、それに基づいたアクションを起こすことができます。

NSNotificationCenterはデザインパターンの一つであるオブザーバーパターンを実装するための強力なツールであり、iOS SDKの多くの部分で内部的に利用されています。

アプリケーションが複雑になりコンポーネント間の通信が増えるにつれ、NSNotificationCenterは開発者にとって非常に価値のあるものとなります。

たとえば、アプリケーション内で重要なデータが更新された際に、関連するすべてのビューにその変更を伝える必要がある場合、NSNotificationCenterを使用して一斉に通知を行うことができます。

○NSNotificationCenterの役割とは

NSNotificationCenterの主な役割は、コンポーネント間でカプセル化されたメッセージ伝送を提供することです。

これにより、一部のコンポーネントが他のコンポーネントに依存することなく、必要な情報を効率的に共有できます。

また、特定のイベントが発生したことをアプリケーションの他の部分に通知する際にも使用されます。

例えば、ダウンロードが完了したことや、ユーザーが特定のアクションを取ったことをアプリの他の部分に通知するときなどが考えられます。

○NSNotificationCenterの基本的な概念

NSNotificationCenterを使用するには、通知を送信するオブジェクトと、その通知を受信して何らかのアクションを起こすオブジェクトを理解する必要があります。

通知の送信は、中央の通知ディスパッチャーであるNSNotificationCenterのインスタンスを通じて行われます。

通知の受信には、特定の通知に対する監視を設定することが求められ、これには通知の名前と、通知を受け取ったときに実行するセレクタ(メソッドのポインタ)が必要です。

●NSNotificationCenterの使い方

NSNotificationCenterを使用する基本的なプロセスは、通知の投稿、通知の監視と受信、および通知の削除の三段階に分けられます。

これらのステップを通じて、アプリケーション内で発生したイベントを他のコードブロックに伝達し、反応させることができます。

○サンプルコード1:通知の送信方法

Objective-Cでの通知の送信は、NSNotificationCenterオブジェクトのpostNotificationName:object:userInfo:メソッドを使用して行われます。

ここでは、通知の名前、通知を送るオブジェクト、およびユーザー情報を含む辞書を指定できます。

// 通知を送信するコード
[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"MyNotificationName" 
                  object:self 
                userInfo:@{ @"key": @"value" }];

このコードではdefaultCenterメソッドを通じてシングルトンのNSNotificationCenterオブジェクトにアクセスし、MyNotificationNameという名前の通知を送信しています。

userInfo辞書には、通知と共に送りたい情報をキーと値のペアで指定しています。

○サンプルコード2:通知の受信方法

通知を受信するには、NSNotificationCenterに対して特定の通知名と、その通知を受け取ったときに実行されるセレクタを登録します。

// 通知を受信するための登録コード
[[NSNotificationCenter defaultCenter] 
    addObserver:self 
       selector:@selector(handleNotification:) 
           name:@"MyNotificationName" 
         object:nil];

// 通知を処理するメソッド
- (void)handleNotification:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    NSString *value = userInfo[@"key"];
    // 通知に含まれるユーザー情報を使用して何かの処理をする
}

このサンプルでは、MyNotificationNameという名前の通知に対する監視を設定しており、その通知がポストされるとhandleNotification:メソッドが呼び出されます。

objectパラメータをnilに設定することで、どのオブジェクトから送られた通知でも受け取れるようになります。

○サンプルコード3:通知のカスタマイズ方法

通知のカスタマイズは、userInfo辞書に任意のデータを含めることで実現できます。

これにより、受信者は通知と共に送られてくる情報をもとに具体的なアクションを取ることができます。

// カスタマイズされた情報を含む通知を送信するコード
[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"MyCustomNotification" 
                  object:self 
                userInfo:@{ @"customKey": @"customValue", @"anotherKey": @42 }];

このコードでは、カスタムキーと値を含んだ通知を送信しています。

受信する側では、これらのカスタム情報に基づいて適切な処理を行うことができます。

○サンプルコード4:通知の削除方法

オブジェクトがもはや通知を受け取る必要がない場合、またはオブジェクトが破棄される前には、監視を解除することが重要です。

これにより、メモリリークや他のリソースの問題を防ぐことができます。

// 通知の監視を解除するコード
[[NSNotificationCenter defaultCenter] removeObserver:self];

このコードでは、defaultCenterで取得したNSNotificationCenterオブジェクトに対してremoveObserver:メソッドを呼び出し、現在のオブジェクトが監視している全ての通知の登録を解除しています。

これは通常、オブジェクトのdeallocメソッド内で行われます。

●NSNotificationCenterの応用例

NSNotificationCenterは、その柔軟性から多様なシナリオで利用することができます。

アプリケーションの異なる部分が相互に通信する場面で、特にその真価を発揮します。

ここでは、NSNotificationCenterを用いた具体的な応用例をいくつか紹介します。

○サンプルコード5:アプリ内通知の実装

アプリケーションでユーザーが特定のアクションを取ったとき、たとえば商品を購入したときに他のビューコントローラーに通知を送ることがよくあります。

これにより、関連するビューを更新することができます。

// 商品購入通知を送信する
[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"ProductPurchasedNotification" 
                  object:self 
                userInfo:@{ @"productID": @"12345" }];

// この通知を受け取るために、関心のあるビューコントローラーで監視を設定します
[[NSNotificationCenter defaultCenter] 
    addObserver:self 
       selector:@selector(updateProductDisplay:) 
           name:@"ProductPurchasedNotification" 
         object:nil];

// 商品表示を更新するメソッド
- (void)updateProductDisplay:(NSNotification *)notification {
    NSString *productID = notification.userInfo[@"productID"];
    // productIDに基づいてビューを更新する
}

上記のコードでは、「ProductPurchasedNotification」という通知があることを想定しています。

ユーザーが商品を購入すると、商品IDを含む通知が送信され、登録されたセレクタupdateProductDisplay:が呼び出されます。

その結果、関連するビューが最新の情報で更新される流れを示しています。

○サンプルコード6:複数の通知を管理する

複数の通知を効率的に管理するために、NSNotificationCenterを使用することもできます。

例えば、アプリケーションがネットワークの状態変化を監視している場合、接続または切断の各シナリオに応じて異なる通知を送ることが考えられます。

// ネットワーク状態の変化に対する通知を送信するコード例
[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"NetworkConnectionChanged" 
                  object:self 
                userInfo:@{ @"status": @"connected" }];

ここで"NetworkConnectionChanged"という通知を使用し、ネットワークの状態が変わったことをアプリの他の部分に伝えています。

通知を受け取ったオブジェクトは、userInfoから状態を確認し、適切なアクションを取ることができます。

○サンプルコード7:条件付きの通知の実装

特定の条件下でのみ通知を受け取りたい場合、NSNotificationCenterは非常に便利です。

例えば、特定のユーザーがログインした場合にのみ通知を受け取りたいとします。

// ユーザーログイン通知を送信するコード
[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"UserDidLoginNotification" 
                  object:self 
                userInfo:@{ @"userID": @"user123" }];

// 特定のユーザーがログインしたときにのみ反応するように監視を設定
[[NSNotificationCenter defaultCenter] 
    addObserverForName:@"UserDidLoginNotification" 
                  object:nil 
                   queue:[NSOperationQueue mainQueue] 
              usingBlock:^(NSNotification *note) {
                  if ([note.userInfo[@"userID"] isEqualToString:@"user123"]) {
                      // ユーザーuser123がログインしたときのみ行う処理
                  }
}];

この例では、ユーザーIDが"user123"である場合に限り、特定の処理を行うブロックを設定しています。

ブロックを使うことで、通知の受信時に追加の条件判断を行うことが可能です。

●注意点と対処法

NSNotificationCenterを使う際には、いくつかの重要な注意点があります。

これらを理解し、適切に対処することで、バグや予期しない動作を避け、アプリケーションのパフォーマンスを維持することができます。

○NSNotificationCenterの使用時の注意点

NSNotificationCenterを使用する際の最も一般的な問題は、通知の監視を解除することを忘れることです。

オブジェクトが破棄された後も通知の監視が残っていると、存在しないインスタンスにメッセージを送ろうとしてクラッシュを引き起こす原因となります。

また、通知の監視を解除しないと、予期しないタイミングで通知が受信されることもあります。

// 監視を解除することを忘れずに
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

このコードは、オブジェクトが解放される際にNotificationCenterから自身を監視解除することを示しています。

deallocメソッド内でremoveObserver:を呼び出すことで、メモリリークやクラッシュのリスクを減らします。

○通知が受け取れない時の対処法

通知が予定通りに受け取れない場合、通知を送信するタイミングや監視を設定するタイミングが原因であることが多いです。

たとえば、通知の監視を設定する前に通知が送信されていたり、監視する通知の名前を間違えていたりすると、通知を受け取ることができません。

// 監視を設定するタイミングを確認する
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] 
        addObserver:self 
           selector:@selector(someMethod:) 
               name:@"NotificationName" 
             object:nil];
}

上記のサンプルコードは、ビューコントローラーのviewWillAppear:メソッド内で通知の監視を開始しています。

これはビューが表示される直前であり、通常はここでの設定が適切です。

○メモリリークを避けるための対処法

NSNotificationCenterを用いる際にメモリリークを避けるためには、通知の監視を不要になった時点で解除することが重要です。

特にブロックを使用して通知を監視する場合は、強参照サイクルが発生しないように注意が必要です。

__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] 
    addObserverForName:@"SomeNotification" 
                object:nil 
                 queue:[NSOperationQueue mainQueue] 
            usingBlock:^(NSNotification * _Nonnull note) {
                [weakSelf someMethod];
}];

この例ではweakSelfを使用して、ブロック内でselfが強参照されることを防いでいます。

これにより、オブジェクトが通知とともにメモリに保持され続けることを防ぎ、メモリリークのリスクを減らすことができます。

●Objective-Cのカスタマイズ方法

Objective-Cでは、カスタマイズ性が非常に高く、開発者が独自の機能を追加することができます。

これにはカテゴリや拡張、独自クラスの作成などが含まれますが、ここでは特にNSNotificationCenterをカスタマイズする方法に焦点を当てて解説します。

○サンプルコード8:独自の通知を作成する

Objective-Cでは、既定の通知以外にも独自の通知を作成して、アプリケーション特有のイベントを管理することができます。

下記のコードは、特定の状況で使用されるカスタム通知の作成方法を表しています。

// 通知名の定義
NSString *const MyCustomNotification = @"MyCustomNotification";

// 通知の投稿
[[NSNotificationCenter defaultCenter] 
    postNotificationName:MyCustomNotification 
                  object:nil 
                userInfo:@{@"Key": @"Value"}];

このコードは、MyCustomNotificationという名前の新しい通知を定義し、それをアプリケーションのどこからでも投稿できるようにしています。

userInfo辞書には、通知と共に送りたい任意の情報を格納できます。

○サンプルコード9:通知にユーザー情報を付与する

NSNotificationCenterの通知にユーザー情報を付与することで、受信者がより多くのコンテキスト情報を得られるようになります。

下記のコードでは、ユーザー情報を付与して通知を投稿する方法を表しています。

// ユーザー情報を付与して通知を投稿する
NSDictionary *userInfo = @{@"userID": @42, @"userName": @"John Doe"};
[[NSNotificationCenter defaultCenter] 
    postNotificationName:@"UserInformationNotification" 
                  object:self 
                userInfo:userInfo];

この例では、ユーザーIDとユーザー名をuserInfo辞書に入れ、通知に添付しています。

この情報は後で通知の受信者によって取り出され、利用されることになります。

○サンプルコード10:通知の優先順位を設定する

Objective-Cでは、特定の通知が他よりも優先して扱われるようにすることは直接的な方法ではできませんが、受信側での通知の扱い方で優先順位を管理することが可能です。

例えば、アプリケーションが特定の通知を受け取った際には、他の通知を遅延させるなどの処理を行うことが考えられます。

// 通知の優先順位を制御するためのロジックの実装例
- (void)receiveNotification:(NSNotification *)notification {
    if ([notification.name isEqualToString:@"HighPriorityNotification"]) {
        // 高優先度の通知を処理する
    } else {
        // 他の通知を遅延して処理する
    }
}

このコードスニペットでは、受信した通知の名前をチェックし、"HighPriorityNotification"という名前の通知の場合には特別な処理を行うことで、優先順位を設定しています。

まとめ

この記事を通して、Objective-CとNSNotificationCenterの基本から応用、カスタマイズ方法に至るまでの知識を幅広くカバーしました。

Objective-Cは、C言語にオブジェクト指向の概念を追加した強力なプログラミング言語であり、iOSやmacOSアプリケーションの開発に広く使用されています。

NSNotificationCenterは、アプリケーション内でのコンポーネント間通信を扱う際に特に有用で、通知の送信、受信、カスタマイズ、優先順位の管理などのために利用できます。

プログラミングは絶えず進化する分野であり、新たな発見と学びが常にあるため、好奇心を持って新しい知識を追求し続けましょう。