KVO KVC Notification

第一次写这种文章 没有什么经验 主要是统揽了一遍知识点发现一些薄弱处给自己看加深印象,同样预防以后忘了的时候自己查阅,不一定准确,如果对看到的同样是初学者的人有些帮助当然就更好了~

KVC

(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。而不是在编译时确定,这也是iOS开发中的黑魔法之一。很多高级的iOS开发技巧都是基于KVC实现的。目前网上关于KVC的文章在非常多,有的只是简单地说了下用法,有的讲得深入但是在使用场景和最佳实践没有说明,我写下这遍文章就是给大家详解一个最完整最详细的KVC。

使用方法

比如你有一个汽车类(Car),汽车类目下有两个属性分别是汽车名(carName),汽车价格(carPrice),使用KVC可以给这两个属性快速的赋值

Car* car=[Car alloc]init];

NSDictionary * dict=@{@"carName":@2.4,@"carPrice":@3.2};

[dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnullkey,id  _Nonnullobj,BOOL*_Nonnullstop) {

      [car setValue:objforKey:key];

}];

NSLog{@"car %@,%@",carName,carPrice};

如果dic中的属性有Car类中没有的,如多出一个生产日期,此时需要在Car中重写-(void)setValue:(id)value forUndefinedKey:(NSString*)key方法否则将会报错

-(void)setValue:(id)value forUndefinedKey:(NSString*)key{

         NSLog(@"try setVaule %@ for Key %@ but not success because this property  does not exist in class",value,key);

}

取值例子

[car valueForKey:@"carName"];

若取值key不在属性中,则需要重写-(id)valueForUndefinedKey方法

若Car中有个属性是结构体,如加上一个产地(from),产地中包含城市(city)省份(province)则可以用下面方法取值

[car valueForKey:@"from"]valueForKey:@"city"];

//或者

 [car valueForKeyPath:@"from.province"];

若有多辆汽车需要计算车辆的平均价格

[[NSArraycars valueForKeyPath:@"@avg.carPrice"] floatValue];

//同样还有@sum,@max,@min以及@count写法计算

KVO

KVO全称KeyValueObserving,是苹果提供的一套事件通知机制。允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。由于KVO的实现机制,所以对属性才会发生作用,一般继承自NSObject的对象都默认支持KVO。

如对下载进度的监听:有两个类展示类(Displayer),下载类(Downloader),Displayer需要对Downloader中的属性进度(progress)进行监听用以展示,步骤如下

Dispalyer中创建属性Downloader* downloader

downloder=[Downloader alloc]init];

1、Displayer向Downloader注册

//options一般常用new与old,数值修改往往是一个过程,分别对应修改之前和之后的值

[_downloader addObserver:self forKeyPath:@"progress" options:NSKeyValueObservingOptionNew context:nil];

2、Downloader通知Displayer,在Displayer中实现

-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionaryid> *)change context:(void*)context{

        if([keyPath isEqualToString:@"progress"])

        {

                   //获取progress值

                    NSNumber* progress=change[NSKeyValueChangeNewKey];

                   //做你想做的事情就可以了;

        }

}

3、取消注册

[_downloader removeObsver:self forKeyPath:@"progress"];


Notification(更新)

与kvo的区别 kvo是在对象上添加观察者,而notification是在通知上添加观察者

Application state状态NotRunning  foreground(InActive Active) Background Suspended Terminate 使用通知观察Application的变化

//name是通知名称 object通知发送者

[[NSNotificationcCenter defaultCenter] addObsever:self addSelector@selector(func:) name:UIApplictionDidEnterBackgroundNotification object:nil];

//发送通知

[[NSNotificationcCenter defaultCenter] postNotificationName:UIApplictionDidEnterBackgroundNotification object:[UIApplication sharedApplication] userInfo:nil];

//处理通知

-(void)Func:(NSNotification*)notification{

//handle notification notification中包含通知名name,发送方object,发送的数据NSDictionary* userInfo

}

//remove

[[NSNotificationcCenter defaultCenter] removeObserver:self name:UIApplictionDidEnterBackgroundNotification object:[UIApplication sharedApplication]];//移除指定observer

//移除所有observer

[[NSNotificationcCenter defaultCenter] removeObserver:self ];

你可能感兴趣的:(KVO KVC Notification)