(二十三)通知机制及其应用
键盘出现后,应该让工具条上升键盘的高度。
注意:键盘的监听是不设置代理的,而是通过通知机制(用于多对象通信)。
通知中心(NSNotificationCenter)用于对象之间的通信,类似于代理(可以在两个对象之间互相传递消息),而通知可以一对多。
通知和代理的区别:后者是一对一,前者可以多对多(发布者也是接收者,可以有多个发布者)。
每个App都有唯一的通知中心实例,专门负责协助不同对象之间的消息通信。
步骤:
1.对象A向通知中心发布通知 2.通知中心向其他对象传递通知 3.处理通知
一个完整的通知包含通知的名称、发布者、额外信息(userInfo字典)三个属性。
为了测试,模拟新闻机构对个人发送的消息:
首先建立新闻机构和个人:
新闻机构
@interface NewsCompany : NSObject @property (nonatomic, copy) NSString *name; @end
个人:注意方法传入的参数为通知对象。
@interface Person : NSObject @property (nonatomic, copy) NSString *name; - (void)newsCome:(NSNotification *)note; @end
1.首先建立个人和新闻机构对象:
NewsCompany *tx = [[NewsCompany alloc] init]; tx.name = @"腾讯新闻"; NewsCompany *sina = [[NewsCompany alloc] init]; sina.name = @"新浪新闻"; Person *p1 = [[Person alloc] init]; p1.name = @"张三(军事新闻)"; Person *p2 = [[Person alloc] init]; p2.name = @"李四(娱乐新闻)"; Person *p3 = [[Person alloc] init]; p3.name = @"王五(通吃)";接着获取通知中心:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];2.然后通过通知中心为对象注册要接收的消息发送者与消息类型:注意慎用nil,系统通知很多,耗费性能。
/** * 传入参数为通知中心 * * @param addObserver 通知对象 * * @param SEL 通知对象的回调方法 * * @param name 接收的通知类型,nil代表全部接收 * * @param object 接收的通知发布者,nil代表全部接收 * */ [center addObserver:p1 selector:@selector(newsCome:) name:@"army_news_come" object:tx];这里代表的是p1这个对象只接受tx的“army_news_come”类型的新闻。
回调方法的第一个参数即为传入的Notification对象,使用点语法访问object即可得到通知对象,通知对象有name和userInfo两个属性:
- (void)newsCome:(NSNotification *)note{ NewsCompany *obj = note.object; NSLog(@"%@收到了%@发送的通知,通知内容是%@",self.name,obj.name,note.userInfo); }
为了验证功能,可以再加入一个人,接收所有的消息:
[center addObserver:p3 selector:@selector(newsCome:) name:nil object:nil];3.最后便是发布消息:
/** * 传入参数为通知中心 * * @param postNotificationName 消息类型 * * @param object 发布者 * * @param userInfo 额外信息字典 * */ [center postNotificationName:@"army_news_come" object:tx userInfo: @{@"title":@"新闻标题", @"intro":@"新闻内容"}]; [center postNotificationName:@"army_news_come" object:sina userInfo: @{@"title":@"新闻标题", @"intro":@"新闻内容"}];
4.观察结果可知,p1(张三)只收到了腾讯新闻的army_news_come,而p3收到了所有新闻:
2015-02-07 11:59:55.595 通知机制[2310:119365] 张三(军事新闻)收到了腾讯新闻发送的通知,通知内容是{ intro = "\U65b0\U95fb\U5185\U5bb9"; title = "\U65b0\U95fb\U6807\U9898"; } 2015-02-07 11:59:55.596 通知机制[2310:119365] 王五(通吃)收到了腾讯新闻发送的通知,通知内容是{ intro = "\U65b0\U95fb\U5185\U5bb9"; title = "\U65b0\U95fb\U6807\U9898"; } 2015-02-07 11:59:55.596 通知机制[2310:119365] 王五(通吃)收到了新浪新闻发送的通知,通知内容是{ intro = "\U65b0\U95fb\U5185\U5bb9"; title = "\U65b0\U95fb\U6807\U9898"; }
UIDevice类提供了一个单粒对象(只能创建一个对象),它代表着设备,可以通过它获取设备的信息。
通过[UIDevice currentDevice]获取这个单粒对象。
它返回的内容有 设备旋转、电池状态、近距离传感器等。
在键盘状态改变时,也会发送通知。
UIKeyboard....开头的通知。
为了保持同步,应该找Will开头的方法。
使用UIKeyboardWillChangeFrameNotification通知,在键盘位置尺寸改变时发通知。
注意:非ARC开发一定要主动移除通知,使用消息中心的removeObserver方法。
一般方法是在对象销毁时移除self的通知,否则会有野指针错误引发应用崩溃。
有addObserver也要有removeObserver