[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sayHello:) name:HelloWorldNotification object:nil];
これに従って、自前で作るシングルトンクラスもなんちゃらセンターと言う名前で作りがちです。僕の場合、
- SupportCenter
- ActivityCenter
- DownloadCenter
などなど。それぞれのクラスにクラスメソッドとしてsharedCenterというメソッドを定義して使ってます。こんな感じ。
[[SupportCenter sharedCenter] alertError:error];
このパターン、便利なんですがコードの中では結局グローバル変数を使って管理するという、まああまり見たくないコードでして、アナライザーに文句言われないためにもちゃんと終了時にグローバル変数を破棄してあげる必要があったり。簡単なことだけどちょっと面倒くさい。
というわけで、メタに考えました。シングルトンを管理するシングルトンクラス、SharedCenter。
SharedCenter.h
// // SharedCenter.h // Ramblin // // Created by Yosuke Suzuki on 10/03/27. // Copyright 2010 Kanshin, Inc.. All rights reserved. // #import <foundation/foundation.h> @interface SharedCenter : NSObject + (id)center:(Class)cls; + (void)registerCenter:(id)center forClass:(Class)cls; @end
SharedCenter.m
// // SharedCenter.m // Ramblin // // Created by Yosuke Suzuki on 10/03/27. // Copyright 2010 Kanshin, Inc.. All rights reserved. // #import "SharedCenter.h" @implementation SharedCenter static NSMutableDictionary *sharedCenters = nil; + (void)initialize { sharedCenters = [[NSMutableDictionary alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeCenters:) name:UIApplicationWillTerminateNotification object:nil]; } + (id)center:(Class)cls { id center = nil; @synchronized(sharedCenters) { NSString *className = NSStringFromClass(cls); center = [sharedCenters objectForKey:className]; if (!center) { center = [[cls alloc] init]; [sharedCenters setObject:center forKey:className]; [center release]; } } return center; } + (void)registerCenter:(id)center forClass:(Class)cls { @synchronized(sharedCenters) { [sharedCenters setObject:center forKey:NSStringFromClass(cls)]; } } + (void)closeCenters:(NSNotification *)notification { [sharedCenters release]; sharedCenters = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end
このクラスを使えば、どんなクラスでも簡単にシングルトンパターンが使えます。しかもグローバル変数は一つだけ。すっきりです。
SupportCenter.h
@interface SupportCenter : NSObject { ... } + (SupportCenter *)sharedCenter; // 定義を追加 ...
SupportCenter.m
#import "SupportCenter.m.h" #import "SharedCenter.h" @implementation ActivityCenter // 実装を追加 + (ActivityCenter *)sharedCenter { return [SharedCenter center:[self class]]; } ...
0 件のコメント:
コメントを投稿