• 通知中心和通知


    1.首先通知中心和通知是两码事.

    通知中心是一个类---NSNotificationCenter,通知是另一个类---NSNotification.

    NSNotification是对一个通知的描述,即一个通知应该包括哪些信息.哪些行为.

    通知有三个属性

    @property (readonly, copy) NSString *name;通知的名字.(放假通知)
    @property (nullable, readonly, retain) id object;通知的发布者.(班主任)
    @property (nullable, readonly, copy) NSDictionary *userInfo;通知的具体信息.(什么时候放假,什么时候收假,放假期间是否有作业,放假不要到河边玩)

    初始化有两个方法

    - (instancetype)initWithName:(NSString *)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo NS_AVAILABLE(10_6, 4_0) NS_DESIGNATED_INITIALIZER;
    - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

    通知有一个分类---NSNotificationCreation,用于创建通知,其实就是快速创建通知方法.

    该分类有三个方法:

    + (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject;//创建一个通知,包含通知的名称,通知的发布者
    + (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;//创建一个通知,包含通知的名称,通知的发布者,通知的具体信息
    
    - (instancetype)init /*NS_UNAVAILABLE*/;    /* do not invoke; not a valid initializer for this class */   该方法不可用,不能被调用,对于通知这个类来说不是一个有效的初始化方法

    2.通知中心

    通知中心其实就是不同对象间通信的中间人.比如有对象A,B.想要实现A,B对象间的通信,信息传递,就可以使用通知中心实现.A通过通知中心的POST方法发布通知,B通过通知中心的addObserver方法可以接收通知;

    有些地方说每一个应用程序都内置了一个NSNotificationCenter对象.意思是UIApplication对象有一个NSNotificationCenter类型的属性.?然而查看UIApplication类,并没有这个属性.通过查询官方文档,可知每一个运行中的Cocoa应用程序默认有一个NSNotificationCenter对象,"Each running Cocoa program has a default notification center.";

    作用范围:NSNotificationCenter只能在一个应用程序中实现消息的传递,如果希望在不同程序中实现消息传递,苹果官方建议使用---NSDistributedNotificationCenter.

    "An NSNotificationCenter object can deliver notifications only within a single program. If you want to post a notification to other processes or receive notifications from other processes, use an instance of NSDistributedNotificationCenter."

    3.通知中心的属性

        @package
        void * __strong _impl;
        void * __strong _callback;
        void *_pad[11];

    ??package的权限还是不太清楚

    ??这几个属性啥意思??回头查,这里不是重点

    4.通知中心的方法

    >1获得通知中心

    + (NSNotificationCenter *)defaultCenter;

    >2.添加通知的接收者

    - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject;
    参数含义:
    observer:通知的接收者.某个通知由谁来接收(程序狗--我)
    aSelector:接收者接收到通知后调用的方法(写代码);会把通知对象当参数传递
    name:通知的名称.(做微信项目);如果为nil,可以接受到anObject发布的任何通知
    anObject:通知的发布者.(老大);如果为nil,可以接收到任何对象的通知

    如果name和anObject都为nil,observer可以接受到所有通知.

    方法大意:"程序狗(我)"在接收到"老大"发布的"做微信项目"的通知后就会调用自己的"写代码"方法,

    >3.通知的发布

    - (void)postNotification:(NSNotification *)notification;//发布一个通知
    - (void)postNotificationName:(NSString *)aName object:(nullable id)anObject; //发布一个通知,包括通知的发布者,通知的名字
    - (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;//发布一个通知,包括通知的发布者,通知的名字,通知的具体信息

    >4.移除接收者

    - (void)removeObserver:(id)observer;//移除接收者,observer:要移除的接收者
    - (void)removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject;//移除observer收到的关于anObject发布的名为aName的通知.

    >5.添加接收者(2)

    - (id <NSObject>)addObserverForName:(nullable NSString *)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0);
        // The return value is retained by the system, and should be held onto by the caller in
        // order to remove the observer with removeObserver: later, to stop observation.
    参数含义:
    name:通知的名字
    obj:通知的发布者
    queue:接收到通知后,block执行所在的队列
    block:接收到通知调用的代码段

    5.注意:

    1>当通知的接收者被释放时,必须移除接收者(调用移除接收者方法):

    - (void)removeObserver:(id)observer;
    - (void)removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject;

    就是说,如果接收者释放了,但是没有被移除,那么通知中心还会向接收者发送通知,这就是访问已经被释放的对象,就是野指针访问,故而在MRC机制下需要重写dealloc方法,在该方法中移除接收者.

    6.一些可能会经常用到的通知

    >1.UIDevice通知

    UIDevice,简单地说就是用于描述当前设备的对象.通过该类可以获取当前设备的一些配置信息,比如设备的版本号,设备名称,型号,操作系统.电池状态.

    UIDevice对象会不间断的发布一些通知:

    UIDeviceOrientationDidChangeNotification //设备方向改变
    UIDeviceBatteryStateDidChangeNotification //电池状态改变
    UIDeviceBatteryLevelDidChangeNotification  // 电池电量改变
    UIDeviceProximityStateDidChangeNotification // 近距离传感器,,接近某些东西的状态改变

    >2.键盘的通知

    UIKeyboardWillShowNotification;//键盘将要出现
    UIKeyboardDidShowNotification;//键盘已经出现
    UIKeyboardWillHideNotification;//键盘将要隐藏
    UIKeyboardDidHideNotification;//键盘已经隐藏

    UIKeyboardWillChangeFrameNotification  //键盘将要改变位置

     UIKeyboardDidChangeFrameNotification //键盘已经改变位置

    键盘的通知会附带一些具体信息:userInfo

    UIKeyboardFrameBeginUserInfoKey   //键盘位置改变前的frame
    UIKeyboardFrameEndUserInfoKey       //键盘位置改变后的frame   
    UIKeyboardAnimationDurationUserInfoKey //键盘位置改变的动画时间
    UIKeyboardAnimationCurveUserInfoKey    //键盘动画执行的节奏(快慢)????
    UIKeyboardIsLocalUserInfoKey 
    UIKeyboardCenterBeginUserInfoKey 
    UIKeyboardCenterEndUserInfoKey   
    UIKeyboardBoundsUserInfoKey                 

     7.通知和代理之间的异同:

    相同:

    都可以实现对象间数据,消息传递,通信

    不同:

    代理需要告诉确定的对象发生了什么,通知不需要,一个对象发布通知,根本不用管谁会接收到这个通知.

    8.示例代码

    #import <Foundation/Foundation.h>
    #import "Boss.h"
    #import "Me.h"
    #import "Boss2.h"
    #import "Someone.h"
    //boss(腾讯老大)的通知
    static NSString *const WeChatDevelop = @"微信项目开发";
    static NSString *const QQDevelop = @"QQ项目开发";
    //boss2(新浪老大)的通知
    static NSString *const WeiBoDevelop = @"微博项目开发";
    static NSString *const SinaReaderDevelop = @"新浪读书项目开发";
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            //创建通知的发布者和接收者
            Boss *boss = [[Boss alloc]init];
            boss.name = @"腾讯";
    
            Boss2 *boss2 = [[Boss2 alloc]init];
            boss2.name = @"新浪";
    
    
            Me *me = [[Me alloc]init];
            me.name = @"王大锤";
            Someone *someone = [[Someone alloc]init];
            someone.name = @"二狗子";
    
    
            //1.获取通知中心
            NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    
    //        逗比程序员成为通知接收者
    //        我成为腾讯的扣扣项目的接收者
            [notificationCenter addObserver:me selector:@selector(writeQQ:) name:nil object:boss];
    // someone成为微博项目接收者 [notificationCenter addObserver:someone selector:@selector(writeWeiBo:) name:WeiBoDevelop object:boss2]; // 2.老板发布通知 // 腾讯发布通知 [notificationCenter postNotificationName:WeChatDevelop object:boss userInfo:@{@"老板":boss.name,@"项目名称":@"微信开发"}]; [notificationCenter postNotificationName:QQDevelop object:boss userInfo:@{@"老板":boss.name,@"项目名称":@"QQ开发"}]; // 新浪发布通知 [notificationCenter postNotificationName:WeiBoDevelop object:boss2 userInfo:@{@"老板":boss.name,@"项目名称":@"微博开发"}]; [notificationCenter postNotificationName:SinaReaderDevelop object:boss2 userInfo:@{@"老板":boss.name,@"项目名称":@"新浪读书开发"}]; } return 0; }

    控制台输出取决于添加接收者代码:

    //        我成为腾讯的扣扣项目的接收者
            [notificationCenter addObserver:me selector:@selector(writeQQ:) name:nil object:boss];
    可以接收到boss发出的所有通知
            [notificationCenter addObserver:me selector:@selector(writeQQ:) name:nil object:nil];
    可以接受到boss,boss2(如果有其他对象也可以)发出的所有通知.
    //        someone成为微博项目接收者
            [notificationCenter addObserver:someone selector:@selector(writeWeiBo:) name:WeiBoDevelop object:boss2];
    可以接收到boss2的微博开发的通知

    9.通知的本质

    个人想法:

    程序最底层是函数,方法(都是具有特定功能的代码段)的调用.

    假设有对象A,B和通知中心;

    A通过通知中心发布通知,调用post方法,意味着,将传入的参数,设置给NSNotification的属性(我猜测是不是这样),主要的用userInfo记录著需要传递的数据.那么add方法是如何将post方法中传入的数据传递给接收者呢?

  • 相关阅读:
    第六章 类(Class) 和对象(Object)
    如何在windows Server 2008虚拟机上安装SQLServer2008数据库
    小票打印机乱码问题
    SQLSERVER 的联接查询写法
    VMware下安装CentOS6.5
    疯狂java讲义--笔记
    学习Java第一篇——Java 安装及环境搭配
    informix数据迁移工具使用介绍
    informix 存储过程结构
    输入身份证号码自动读取生日与性别(delphi)
  • 原文地址:https://www.cnblogs.com/yufang/p/5204501.html
Copyright © 2020-2023  润新知