LoginSignup
26

More than 5 years have passed since last update.

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

Posted at

最近つかっている 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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26