KVO,NSNotification,delegete及block区别
来源:互联网 发布:html5简单小游戏源码 编辑:程序博客网 时间:2024/05/17 08:19
KVO
KVO是cocoa框架实现的观察者模式,一般同KVC搭配使用,通过KVO可以监测一个值的变化,比如View的高度变化,是一对多的关系,一个值的变化会通知所有的观察者
Key-Value Observing (KVO) 建立在 KVC 之上,它能够观察一个对象的 KVC key path 值的变化
//KVO主要用于model类,当Model类的一个属性值发生变化的时候,会触发事件
//在设计模式中有一种设计模式是观察者模式
//kvo是观察者模式的实现方式
//kvo是观察者模式的实现方式
//kvo里面涉及的几个概念
//1.被观察者一般是我们的Model类
//2.观察者一般是controller
//3.key 一般是model类的属性
//2.观察者一般是controller
//3.key 一般是model类的属性
//4.value 一般是属性对应的value值
1.被观察者
@interfacePerson :NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *gender;
@end
//使用步骤
//1.创建一个被观察者
_p= [[Personalloc]init];
_p.name= @“a";
_p.name= @“a";
_p.gender= @“b";
//2.为被观察者指定观察者
//观察者属性key new/old/inital/Prior参数
//观察者属性key new/old/inital/Prior参数
[_paddObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld context:nil];
//4.改变属性的value值
_p.name= @“c";
_p.name= @“d";
_p.name= @“c";
_p.name= @“d";
_p.gender= @“e";
// whenever an observed key path changes, this method will be called
//3.实现回调方法
//3.实现回调方法
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context{
NSLog(@"keyPath:%@",keyPath);
NSLog(@"object:%@",object);
NSLog(@"change:%@",change);
NSLog(@"object:%@",object);
NSLog(@"change:%@",change);
}
//5.在dealloc方法里面移除观察者
- (void)dealloc{
[_premoveObserver:selfforKeyPath:@"name"];
- (void)dealloc{
[_premoveObserver:selfforKeyPath:@"name"];
}
KVO的实现分析
使用观察者模式需要被观察者的配合,当被观察者的状态发生变化的时候通过事先定义好的接口(协议)通知观察者.在KVO的使用中我们并不需要向被观察者添加额外的代码,就能在被观察者的属性变化的时候得到通知,这个功能是如何实现的?同KVC一样依赖于强大的Runtime机制
系统实现KVO有以下几个步骤:
- 当类A的对象第一次被观察的时候,系统会在运行期动态创建类A的派生类。我们称为B。
- 在派生类B中重写类A的setter方法,B类在被重写的setter方法中实现通知机制。
- 类B重写会 class方法,将自己伪装成类A。类B还会重写dealloc方法释放资源。
- 系统将所有指向类A对象的isa指针指向类B的对象。
KVO同KVC一样,通过isa-swizzling技术来实现.当观察者被注册为一个对象的属性的观察对象的isa指针被修改,指向一个中间类,而不是在真实的类.其结果是,isa指针的值并不一定反映实例的实际类
所以不能依靠isa指针来确定对象是否是一个类的成员,应该使用class方法来确定对象实例的类
这就是KVO 的作用,它通过 key path 观察对象的值,当值发生变化的时候会收到通知
NSNotification
NSNotificaiion是通知,也是一对多的使用场景.在某些情况下,KVO和NSNotification是一样的,都是状态变化之后告知对方.NSNotification的特点,就是需要观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但其优点是监听不局限于属性的变化,还可以对多种多样的状态化进行jiant,监听范围广,使用也更灵活
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// Override point for customization after application launch.
//创建一个本地通知
UILocalNotification *localNot = [[UILocalNotificationalloc]init];
//先做一下iOS版本的判断,因为iOS8.0以后注册发生了一些变化,必须设置UIUserNotificationSettings
if ([[UIDevicecurrentDevice].systemVersionfloatValue] >=8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettingssettingsForTypes:UIUserNotificationTypeAlert| UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
//注册这些settings
[[UIApplicationsharedApplication]registerUserNotificationSettings:settings];
}
//设置本地通知的一些属性
//设置通知的开始时间
NSDate *fireDate = [NSDatedateWithTimeIntervalSinceNow:10];
localNot.fireDate= fireDate;
//设置时区
localNot.timeZone= [NSTimeZonedefaultTimeZone];
//设置重复频率(现在为一分钟)
localNot.repeatInterval= NSCalendarUnitMinute;
//推送显示的内容
// Override point for customization after application launch.
//创建一个本地通知
UILocalNotification *localNot = [[UILocalNotificationalloc]init];
//先做一下iOS版本的判断,因为iOS8.0以后注册发生了一些变化,必须设置UIUserNotificationSettings
if ([[UIDevicecurrentDevice].systemVersionfloatValue] >=8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettingssettingsForTypes:UIUserNotificationTypeAlert| UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
//注册这些settings
[[UIApplicationsharedApplication]registerUserNotificationSettings:settings];
}
//设置本地通知的一些属性
//设置通知的开始时间
NSDate *fireDate = [NSDatedateWithTimeIntervalSinceNow:10];
localNot.fireDate= fireDate;
//设置时区
localNot.timeZone= [NSTimeZonedefaultTimeZone];
//设置重复频率(现在为一分钟)
localNot.repeatInterval= NSCalendarUnitMinute;
//推送显示的内容
localNot.alertBody= @"12点了";
//标题
localNot.alertTitle= @"提醒";
//设置声音
localNot.soundName= UILocalNotificationDefaultSoundName;
//localNot.soundName = @"XiaoPingGuo.aiff";
//设置角标个数
localNot.applicationIconBadgeNumber= 2;
//设置userInfo
NSDictionary *dic = [NSDictionarydictionaryWithObject:@"banji"forKey:@"class"];
localNot.userInfo= dic;
//执行通知
[application scheduleLocalNotification:localNot];
return YES;
}
- (void)application:(UIApplication*)application didReceiveLocalNotification:(UILocalNotification*)notification{
[application setApplicationIconBadgeNumber:0];//进入前台
//先得到所有的本地通知
NSArray *localNots = [application scheduledLocalNotifications];
//遍历所有的本地通知找到对应的本地通知
for (UILocalNotification*localin localNots) {
//根据userInfo找到对应的本地通知
NSDictionary *dic = local.userInfo;
if ([[dicobjectForKey:@"class"]isEqualToString:@"banji"]) {
//取消对应的本地通知
[application cancelLocalNotification:local];
}
}
//取消全部本地通知
[application cancelAllLocalNotifications];
}
Delegate
delegate是代理,就是我不想做的事情交给别人做.比如狗需要吃饭,就通过delegate通知主人,主人就会给他做饭,盛饭,倒水,这些操作这些狗都不需要关心,只需要调用delegate(代理人)就可以了,有其他类完成所需要的操作.所以delegate是一对一关系
Block
block是delegate的另一种形式,是函数式编程的一种形式,使用 场景跟delegete一样,相比delegate更灵活,而且代理的实习更直观
KVO一般的使用场景是数据,需求是数据变化,比如股票价格变化,我们一般使用KVO(观察者模式).
delegate一般的使用场景是行为,需求是需要别人帮我做一件事情,比如买卖股票,我们一般使用delegate.
Notification一般是进行全局通知,经纪人也不要知道自己的顾客.Notification是弱关联,利好消息发出,你不需要知道是谁发的也可以做出相应的反应,同理发消息的人也不需要知道接收的人也可以正常发出消息
KVC
kvc是Key Value Coding简称,是一种可以他那个过字符串的名字(key)来访问类属性的机制,而不是通过调用Setter,Getter方法访问
关键方法定义在NSKeyValueCodingProtocol
KVC支持类对象的内 建基本数据类型
使用
获取值
valueForKey: 传入NSString属性的名字。
valueForKeyPath: 属性的路径,xx.xx
valueForUndefinedKey 默认实现是抛出异常,可重写这个函数做错误处理- 修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUnderfinedKey:
setNilValueForKey: 对非类对象属性设置nil时调用,默认抛出异常。
KVC键值查找
搜索单值成员
setValue:forKey:搜索方式
1,首先搜索setKey:方法.(key指成员变量名,首字母大写)
2,上面的setter方法没找到,如果类方法axxessInstanceVariablesDirectly返回YES.那么按key,is Key,key,isKey的顺序搜索成员名. (NSKeyValueCodingCatogery中实现的类方法,默认实现为返回YES)
3,如果没有找到成员变量,调用setValue:forUnderfinedKey:
valueForKey:的搜索方式
1.首先按getKey,key,isKey的顺序查找getter方法,找到直接调用.如果是BOOL,int等内建值类型,会做NSNumber的转换
2.上面的getter没找到,查找countOfKey,objectInKeyAtIndex,KeyAtIndexes格式的方法,如果countOfKey和另外两个方法中的一个找到,那么就会返回一个可以响应NSArray所有方法的代理集合的NSArray消息方法
3.还没找到,查找countOfKey,enumeratorOfKey,memberOfKey格式的方法.如果这三个方法都找到,那么就返回一个可以响应NSSet所有方法的代理集合
4.还是没有找到,如果类方法accessInstanceVariablesDirectly返回YES,那么按key,isKey,key,isKey的顺序搜索成员名
5,再没有找到,调用valueForUndefinedKey
KVC实现分析
KVC运用了isa-swizzing技术,isa-swizzing就是类型混合指针机制,KVC通过isa-swizzing实现其内部查找定位.isa指针(is kind of)指向维护分发表的对象的类,该分发表实际上包含了指向现实类中的方法的指针和其他数据
[site setValue:@"sitename"forKey:@"name"]; //会被编译器处理成
SELsel = sel_get_uid(setValue:forKey);
IMPmethod= objc_msg_loopup(site->isa,sel);
method(site,sel,@"sitename",@"name");
每一个类都由一张方法表,是一个hash表,值是还书指针IMP,SEL的名称就是查表时所有的键
SEL数据类型:查找方法表时所用的键.定义成char*,实质上可以理解成int值
IMP数据类型:他其实就是一个编译器内部实现时候的函数指针,当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型
KVC的内部机制:
一个对象在调用setValue的时候进行了:
1.根据方法名找到运行方法的时候需要的环境参数
2.他会从自己的isa指针结合环境参数,找到具体的方法实现接口
3.再直接查找得来的具体的实现方法
0 0
- KVO,NSNotification,delegete及block区别
- KVO,NSNotification,delegate及block区别
- KVO,NSNotification,delegate及block区别?
- KVO,NSNotification,delegate及block区别
- KVO,NSNotification、Block、Delegate和KVO的区别
- KVC、KVO、NSNotification、delegate 总结及区别
- NSNotification、KVC及KVO
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- 南大软院大神养成计划第五天
- Python解析json
- (第八周项目2)建立链串的算法库
- Linux之——基础命令
- 127.Oracle数据库SQL开发之 数据库对象——类型继承
- KVO,NSNotification,delegete及block区别
- 初探内存管理
- 128.Oracle数据库SQL开发之 数据库对象——用子类型对象代替超类型对象
- Space Replacement
- (第八周项目3)顺序串算法
- 【小程序】青蛙王子
- HDOJ 3783 ZOJ
- IE6的重定向页面无法跳转解决
- 129.Oracle数据库SQL开发之 数据库对象——其他有用的对象函数