iOS--NSNotificationCenter多次接收问题的总结

  通知中心(NSNotificationCenter)是在程序内部提供了一种广播机制,可以一对多的发送通知,通知的使用步骤:创建通知、发送通知、移除通知,创建通知有两种方法,分别为[NSNotificationCenter defaultCenter] addObserver[NSNotificationCenter defaultCenter] addObserverForName:,首先介绍下第一种方法:

  一般最好在viewDidLoad的方法中创建通知,因为该方法只走一次,防止多次创建

  1、创建通知

- (void)viewDidLoad {
     [super viewDidLoad];
     //创建通知
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respond:) name:@"tongzhi" object:nil];
}

//实现响应
- (void)respond:(NSNotification *)notification{
    //通知内容
    NSDictionary *dic = notification.object;    
}

  2、发送通知

 //发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];

  当然你可以传递一些自己封装的数据,通过object就行,如:

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"松",@"name",@"男",@"sex", nil];
 //发送通知
 [[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:dic];

  3、移除通知

  移除通知一般在dealloc中实现,因为越来越多应用支持手势返回,滑回一半又返回等操作,在页面真正销毁的时候移除最好

  移除有两种方法,一个是移除当前页面所有的通知,还有一种移除指定的通知,具体用哪个看实际情况,如下:

-(void)dealloc{
     // 移除当前所有通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    //移除名为tongzhi的那个通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"tongzhi" object:nil];
}

  注意:dealloc方法不走一般原因有三个:

1、ViewController中存在NSTimer ,计时器是否销毁;
2、ViewController中有关的代理 ,要记住delegate的属性应该是assign;
3、ViewController中有Block,Block里面是否有强引用;

   下面介绍第二种使用的通知方法:

  1、创建通知

  这个方法需要一个id类型的值接受

@property (nonatomic, weak) id observe;

  再创建通知

    //Name: 通知的名称
    //object:谁发出的通知
    //queue: 队列,决定 block 在哪个线程中执行, nil 在发布通知的线程中执行
    //usingBlock: 只要监听到通知,就会执行这个 block
   _observe = [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"收到了通知");
    }];

  该方法有个block,要操作的步骤可以直接写在block里面,代码的可读比第一种高,所以用的人更多

  2、发送通知

//与第一种发送通知一样
[[NSNotificationCenter defaultCenter] postNotificationName:@"tongzhi" object:nil];

  3、移除通知

- (void)dealloc {
    //移除观察者 _observe
    [[NSNotificationCenter defaultCenter] removeObserver:_observe];
}

  从移除的方法,应该知道了,为什么第二种创建通知方法时要有一个id类型的值接受,千万不要用第一种的注销方法,这也是我用错了的原因,我创建的时候没用一个值接收,直接这么写:

 [[NSNotificationCenter defaultCenter] addObserverForName:@"tongzhi" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"收到了通知");
    }];

  导致通知未移除而重复创建,执行方法一次比一次多,而移除的时候用

-(void)dealloc{
    //用第二种创建方法错误的移除
    //移除名为tongzhi的那个通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"tongzhi" object:nil];
}

  从而导致程序出问题,还有一点值得注意的是,销毁应该是哪里创建哪里销毁,不要在发送的控制器里执行销毁!!

声明: 转载请注明出处https://www.jianshu.com/p/ab52ee91cbb0

你可能感兴趣的:(iOS--NSNotificationCenter多次接收问题的总结)