最近つかっている NSNotificationCenter がかなり便利だったのでまとめてみた。
ブロック構文を実装しよう。
今回はobj-c開発鬼門のひとつ、ブロック構文を使おうと思う。
循環参照がおこるとメモリリークを起こしてしまうので注意して使いたい。
NSNotificationCenterは前回もだいぶすごい使い方だが、
今回は同じことをブロック構文で実装することで、メソッドを減らします。
今回使うメソッドは以下の3つ
[[NSNotificationCenter defaultCenter] addObserverForName: object: queue: usingBlock:]
[[NSNotificationCenter defaultCenter] removeObserver: name: object:]
[[NSNotificationCenter defaultCenter] postNotificationName:object:userInfo:]
delegateを使わずに、クラス間でメソッドを実行できる。
実装は以下のとおり。
#import "TouchImageView.h"
@interface ViewController : UIViewController
@property (strong, nonatomic) TouchImageView *imageView;
@end
static NSString * const kDetail = @"detail";
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//タッチできる画像を配置する
imageView = [[TouchImageView alloc] initWithImage:[UIImage imageNamed:@"sasamisan"]];
imageView.userInteractionEnabled = YES;
imageView.backgroundColor = [UIColor greenColor];
imageView.frame = CGRectMake(100, 100, 200, 300);
[self.view addSubview:imageView];
__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName: kDetail object: nil queue: nil usingBlock:^(NSNotification *notification){
//渡されたオブジェクトから取り出す
UIImageView *iv = (UIImageView *)[notification object];
NSDictionary *userInfo = [notification userInfo];
//詳細画面に遷移する
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.image = iv.image;
dvc.userName = userInfo[@"name"];
dvc.sex = userInfo[@"sex"];
[self.navigationController pushViewController:dvc animated:YES];
// 使い終わったらきちんとremoveする
[[NSNotificationCenter defaultCenter] removeObserver:observer];
observer = nil;
}];
}
@end
@interface TouchImageView : UIImageView
@end
static NSString * const kDetail = @"detail";
@implementation TouchImageView
//タッチされたら、その画像の詳細に遷移する
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//メソッドに渡す値を設定する
NSDictionary *dic = @{@"name": @"sasami", @"sex":@"female"};
//kDetailという文字列を通知する。一緒にオブジェクトをいろいろ渡す
[[NSNotificationCenter defaultCenter] postNotificationName:kDetail object:self userInfo:dic];
}
@end
DetailViewController は割愛。
前回は通知を受け取った後にメソッドに処理を渡していたが、ブロック構文にすると1箇所にまとめることができる。
注意したい点は、今回ブロック構文の中で_removeobserver_しているところである。
わざわざブロック構文の中でremoveしなくてもよいが、どこかでremoveしない限り、
ずっと残るので注意したい。
逆に、アプリが終了するまで残るので、一度設定するだけでどこからでも呼べるのは使いやすい
このように、NSNotificationCenterには多様な使い道がある。
obj-cに慣れてきたら使ってみたらどうだろうか?