Objective-C
Xcode

ブロック構文を実装!NSNotificationCenterの使い方その3

More than 5 years have passed since last update.

最近つかっている NSNotificationCenter がかなり便利だったのでまとめてみた。

ブロック構文を実装しよう。

今回はobj-c開発鬼門のひとつ、ブロック構文を使おうと思う。

循環参照がおこるとメモリリークを起こしてしまうので注意して使いたい。

NSNotificationCenterは前回もだいぶすごい使い方だが、

今回は同じことをブロック構文で実装することで、メソッドを減らします。

今回使うメソッドは以下の3つ


NSNotificationCenter

[[NSNotificationCenter defaultCenter] addObserverForName: object: queue: usingBlock:]

[[NSNotificationCenter defaultCenter] removeObserver: name: object:]
[[NSNotificationCenter defaultCenter] postNotificationName:object:userInfo:]


delegateを使わずに、クラス間でメソッドを実行できる。

実装は以下のとおり。


ViewController.h


#import "TouchImageView.h"

@interface ViewController : UIViewController
@property (strong, nonatomic) TouchImageView *imageView;
@end


ViewController.m


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



TouchImageView.h

@interface TouchImageView : UIImageView

@end


TouchImageView.m


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に慣れてきたら使ってみたらどうだろうか?

前 : delegateいらず!NSNotificationCenterの使い方その2