您的当前位置:首页正文

通知机制

来源:华拓网

每个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的通信。

任何对象都能向通知中心发布通知(NSNotification),描述自己要做什么。监听者(对它感兴趣的对象)可以申请在某个特定通知发布时(比如电视剧更新)收到这个通知。

通知过程

步骤

1.添加监听者
2.发布通知
3.当监听者对象被销毁时,一定要把他从通知中心移除掉(这一步很重要)

.
.
PS: 用的Command Line Tool ,非Single View Application

Company.h

#import <Foundation/Foundation.h>

@interface Company : NSObject

//属性

//APP名称
@property (nonatomic,copy) NSString *companyName;

//电视名称
@property (nonatomic,copy) NSString *movieName;

@end

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject

//用户名称
@property (nonatomic,copy) NSString *name;

//声明
//当接收到通知的时候,被调用的方法
- (void)reciveNotification:(NSNotification *)noti;

@end

main.m

#import <Foundation/Foundation.h>
#import "Company.h"
#import "Person.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {

    // 实例化      
    // 爱奇艺-老九门
    Company *mysticNine = [[Company alloc] init];
     = @"爱奇艺";
    mysticNine.movieName = @"老九门";

    
    // 爱奇艺-海贼王
    Company *onePiece = [[Company alloc] init];
     = @"爱奇艺";
    onePiece.movieName = @"海贼王";
    
    // 优酷-极限挑战
    Company *impossibleGame = [[Company alloc] init];
     = @"优酷";
    impossibleGame.movieName = @"极限挑战";
    
    
    // 实例化 监听者
    //阿年
    Person *anian = [[Person alloc] init];
    anian.name = @"阿年";
    
    //四七七
    Person *siqiqi = [[Person alloc] init];
    siqiqi.name = @"四七七";
表达效果图

讲解: 阿年和四七七要看电视
在两个网站注册了账号
阿年在 爱奇艺 看 老九门,在 优酷 看 极限挑战
四七七 在 爱奇艺 看 海贼王
好啦没错两个都是我……

1. 注册监听

    //单例模式 defaultCenter
    /*
     为 阿年 注册 老九门 的监听
     addObserver: 监听者
     selector: 接收到通知的时候,调用监听者的方法
     name: 通知的名称
     object: 通知的发布者
     */
    
    [[NSNotificationCenter defaultCenter] addObserver:anian
                                             selector:@selector(reciveNotification:)
                                                 name:@"Nine"
                                               object:mysticNine];
    
    
    // 为 阿年 注册 极限挑战 的监听
    [[NSNotificationCenter defaultCenter] addObserver:anian
                                             selector:@selector(reciveNotification:) name:@"jitiao"
                                               object:impossibleGame];
    
    // 为 四七七 注册 海贼王 的监听
    [[NSNotificationCenter defaultCenter] addObserver:siqiqi
                                             selector:@selector(reciveNotification:)
                                                 name:@"OP"
                                               object:nil];

   
    //完成注册,等着通知
注意
    //object: 可以为nil
    //name: 不能为nil,若为nil,会接收到所有的通知,因为不知道接收哪个
接收了所有的通知(你看混乱了吧)

2. 发布通知

    /*
      发布 老九门 的更新通知
     传递的是字典
     postNotificationName: 必须和注册的时候的名字(name:)保持一致
     object: 消息的发布者
     userInfo: 自定义的消息
     */
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Nine"
                                                        object:mysticNine
                                                      userInfo:@{@"company":mysticNine}];
    
    
    // 发布 海贼王 的更新通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"OP"
                                                        object:onePiece
                                                      userInfo:@{@"company":onePiece}];
    
    // 发布 极限挑战 的更新通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"jitiao"
                                                        object:impossibleGame
                                                      userInfo:@{@"company":impossibleGame}];
     
       }
return 0;
}

Person.m

#import "Person.h"
#import "Company.h"

@implementation Person

- (void)reciveNotification:(NSNotification *)noti
{
//    NSLog(@"%@",noti);
NSLog打印内容
// 取出 userInfo (字典)
NSDictionary *dict = noti.userInfo;

// 取出 公司信息
Company *company = dict[@"company"];
//dict[@"key值"];
//userInfo = {company = "<Company:0x1003000a0>";}} 中的company

NSLog(@"%@, 订阅了 %@, %@ 
    
}
这才是正确的打开方式

3. 移除监听

// 如果 阿年 注销了,但是在通知中心他的消息还在,因为没有被移除。若中心再有更新,还会给阿年发布通知,于是就会发生找不到 阿年 的情况,会导致崩溃。

- (void)dealloc
{
    //一定要把监听者移除
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}