• notification 通知


    1. 定义一个方法

    -(void) update{ }

    2. 对象注册,并关连消息

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(update) name:@"update" object:nil]

    3. 在要发出通知消息的地方

    [[NSNotificationCenter defaultCenter]postNotificationName:@"update" object:nil];

    具体如何使用 Notifications

    1.     通知中心概述
    通知中心实际上是在程序内部提供了消息广播的一种机制。通知中心不能在进程间进行通信。实际上就是一个二传手,把接收到的消息,根据内部的一个消息转发表,来将消息转发给需要的对象。通知中心是基于观察者模式的,它允许注册、删除观察者。
    一个NSNotificationCenter可以有许多的通知消息NSNotification,对于每一个NSNotification可以有很多的观察者Observer来接收通知。
    2.     通知中心两个重要的类
    NSNotificationCenter:这是iOS中通知中心的灵魂,由该类实现了观察者模式,并给开发者提供了诸如注册、删除观察者的接口,我们可以通过一个单例来获得它的实例(注,一个程序内部只有一个NSNotificationCenter实例对象)。
    NSNotification:这是消息携带的载体,通过它,可以把消息内容传递给观察者。其中:name对应消息名称标示。object一般是发送者本身、dictionary则是传递的消息内容。
    3.     通知中心如何使用
    通过下图,我们可以看出,通知中心的使用可以分为4个步骤。
    这里需要额外提一点的是:发送消息不仅仅可以有用户发起,也可以是系统发起。
    当我们注册了某个消息的观察者后,如果有了对应的消息,则观察者会收到相应的消息,并展开处理。这里需要注意的是,当使用完消息之后,不想在接收到消息,则需要把观察者移除,否则会出现错误。

    注册通知:即要在什么地方接受消息
    [[NSNotificationCenter defaultCenter]  addObserver:self selector:@selector (mytest:) name:@" postData " object:nil];
    参数介绍:
    addObserver:观察者,即在什么地方接收通知;
    selector:收到通知后调用何种方法,即回调函数;
    name:通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
    发送通知:调用观察者处的方法。
    [[NSNotificationCenter defaultCenter] postNotificationName:@" postData " object:searchFriendArray];

    例子:

    用户可能使用RaiseMan并打开了几个document, 然后他发现紫色的背景颜色实在是不利于阅读文档正文.

    于是,他打开Preferences panel修改背景颜色,不过令人失望的是,已经存在的文档的背景颜色不会跟着改变.

    于是,这个用户可能会写信给你告诉你这些. 你也许会回复:"defualts会在document创建的时候才读取,

    保存document在打开"实际上,用户想说明的是他希望程序能立马刷新已经打开的文档. 如果这样,那该怎么做呢?

    我们需要把所有打开的document用一个list记录起来么?

    --- 什么是Notification? ---

    这个要求其实也很容易实现. 每个运行中的application都有一个NSNotificationCenter的成员变量,

    它的功能就类似公共栏. 对象注册关注某个确定的notification(如果有人捡到一只小狗,就去告诉我).

    我们把这些注册对象叫做 observer. 其它的一些对象会给center发送notifications(我捡到了一只小狗).

    center将该notifications转发给所有注册对该notification感兴趣的对象. 我们把这些发送notification的对象叫做 poster

    很多的标准Cocoa类会发送notifications: 在改变size的时候,Window会发送notification;

    选择table view中的一行时,table view会发送notification;我们可以在在线帮助文档中查看到标准cocoa对象发送的notification

    在我们的例子中,我们将MyDocumet对象注册为observer. 而preference controller在用户改变color时将发送notification.

    MyDocument在接受到该notification后改变background color

    在MyDocument对象释放前,我们必须从notification center移除我们注册的observer. 一般我们在dealloc方法中做这件事

    -- Notifications 不是什么 --

    当程序员们听到notification center的时候, 他们可能会联想到IPC(进程间通讯).他们认为:

    "我在一个程序中创建一个observer,然后在另外一个程序中发送一个notification". 这个设计没有办法工作的,

    notification center允许同一个程序中的不同对象通许,它不能跨越不同的程序 [Notification 就是设计模 式中的 观察者模式,

    cocoa为我们实现了该模式, 就像Java也有同样的实现一样]

    -- NSNotification 和 NSNotificationCenter

    Notification对象非常简单. 它就是poster要提供给observer的信息包裹. notification对象有两个重要的成员变量:

    name 和 object. 一般object都是指向poster(为了让observer在接受到notification时可以回调到poster)

    所以,notification有两个方法

    - (NSString *)name

    - (id)object

    NSNotificaitonCernter是架构的大脑了.它允许我们注册observer对象, 发送notification, 撤销observer对象注册

    下面是它的一些常用方法

    + (NSNotificationCenter *)defaultCenter

    返回notification center [类方法,返回全局对象, 单件模式.cocoa的很多的全局对象都是通过类似方法实现]

    - (void)addObserver:(id)anObserver

    selector:(SEL)aSelector

    name:(NSString *)notificationName

    object:(id)anObject

    注册anObserver对象:接受名字为notificationName, 发送者为anObject的notification. 当anObject发送名字

    为notificationName的notification时, 将会调用anObserver的aSelector方法,参数为该notification 如图14.1

    . 如果notificationName为nil. 那么notification center将anObject发送的所有notification转发给observer

    . 如果anObject为nil.那么notification center将所有名字为notificationName的notification转发给observer

    - (void)postNotification:(NSNotification *)notification

    发送notification至notification center 如图14.2

    - (void)postNotificationName:(NSString *)aName

    object:(id)anObject

    创建并发送一个notification

    - (void)removeObserver:(id)observer

    移除observer

    -- 发送一个Notification --

    发送notification是其中最简单的步骤了,所以我们从它开始实现.当我们接收到changeBackgroundColor:消息时,

    PreferenceController对象发送一个notification.

    我们将notification命名为@"BNRColorChanged" ,我们使用一个全局常量来指定.(有经验的程序员会使用一个前缀,

    这样避免和其他组件定义的notification混淆)打开PreferenceController.h 添加下面的的外部申明

    extern NSString * const BNRColorChangedNotification;

    在PreferenceController.m中定义常量

    NSString * const BNRColorChangedNotification = @"BNRColorChanged";

    在PreferenceController.m修改changeBackgroundColor:方法

    - (IBAction)changeBackgroundColor:(id)sender

    {

    NSColor *color = [colorWell color];

    NSData *colorAsData =

    [NSKeyedArchiver archivedDataWithRootObject:color];

    [[NSUserDefaults standardUserDefaults] setObject:colorAsData

    forKey:BNRTableBgColorKey];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    NSLog(@"Sending notification");

    [nc postNotificationName:BNRColorChangedNotification object:self];

    }

    -- 注册成为Observer --

    要注册一个observer, 我们必须提供几个要数: 要成为observer的对象;所感兴趣的notification的名字;

    当notification发送时要调用的方法. 我们也可以指定要关注莫个对象的notification.(比如说,我们需要

    关注莫个特定的window的resize的notification)

    编辑MyDocument类的init方法

    - (id)init

    {

    if (![super init])

    return nil;

    employees = [[NSMutableArray alloc] init];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    [nc addObserver:self

    selector:@selector(handleColorChange:)

    name:BNRColorChangedNotification

    object:nil];

    NSLog(@"Registered with notification center");

    return self;

    }

    同时在dealloc方法,将MyDocument从notification center中移除

    - (void)dealloc

    {

    [self setEmployees:nil];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    [nc removeObserver:self];

    [super dealloc];

    }

    -- 处理Notification --

    当一个notification发生时, handleColorChange:方法将被调用. 目前我们在方法中简单的打印一些log.

    - (void)handleColorChange:(NSNotification *)note

    {

    NSLog(@"Received notification: %@", note);

    }

    编译运行程序,看到了我们想要的log了吧

    -- userInfo Dictionary --

    notification对象的object变量是poster,如果我们想要notification对象传递更多的信息,

    我们可以使用user info dictionary. 每个notification对象有一个变量叫 userInfo, 它是一个NSDictionary对象,

    用来存放用户希望随着notification一起传递到observer的其它信息. MyDocument将使用它来得到要改变的color.

    在PreferenceController.m添加userInfo

    - (IBAction)changeBackgroundColor:(id)sender

    {

    NSColor *color = [sender color];

    NSData *colorAsData;

    colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];

    [[NSUserDefaults standardUserDefaults] setObject:colorAsData

    forKey:BNRTableBgColorKey];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    NSLog(@"Sending notification");

    NSDictionary *d = [NSDictionary dictionaryWithObject:color

    forKey:@"color"];

    [nc postNotificationName:BNRColorChangedNotification

    object:self

    userInfo:d];

    }

    在MyDocument.m,从userInfo中读取到color

    - (void)handleColorChange:(NSNotification *)note

    {

    NSLog(@"Received notification: %@", note);

    NSColor *color = [[note userInfo] objectForKey:@"color"];

    [tableView setBackgroundColor:color];

    }

    打开几个窗口,并改变背景颜色,现在,那些打开的窗口的背景颜色立马就变了.

    -- 思考 --

    通常当你将自己的一个对象设置为cocoa某个标准对象的delegate的时候,你同时或许也对该标准对象的notification感兴趣.

    例如,我们实现一个window的delegate来处理 windowShouldClose: , 我们也许会对 NSWindowDidResizeNotification

    这样的notification感兴趣.

    如果一个cocoa标准对象有一个delegate,同时它也发送notification的话, cocoa对象会自动将它的delegate对象注册

    成为observer来接受接受自己的notification. 如果我们实现了一个delegate,那么delegate[也就是我们的对象]

    要怎样声明来接受notification呢?[方法的名字是什么?]

    方法名字其实很简单: 以notification名字为基准, 先将NS前缀去掉,接着将第一个字母改为小写. 在将后面的Notification去掉,

    然后加个冒号:. 例如,为了能接受到window的NSWindowDidResizeNotification, delegate可以实现方法:

    - (void)windowDidResize:(NSNotification *)aNotification

    当window改变大小时,这个方法将自动调用. 对于NSWindow,我们可以在.h或是帮助文档中找到类似的notification

    来实现notification方法.

    -- 挑战 --

    当程序不再是active状态是,让程序发出beep. 当unactive时,NSApplication会发送

    NSApplicationDidResignActiveNotification的notificaiton. 而我们的AppController是NSApplication的delegate.

    函数NSBeep()可以用来发出beep声音

  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/hereiam/p/3813631.html
Copyright © 2020-2023  润新知