关闭

KVC、KVO

标签: iosKVCKVO
268人阅读 评论(0) 收藏 举报
分类:

KVC、KVO

1、       键值编码KVC

很多语言如Java、C#等通过反射机制可以读写一个对象的属性,在一些特殊场合,这种方式可以方便管理对象属性。在OC中,我们不必进行任何操作就可以动态的读写属性值,这种方式就是KeyValue Coding,简称为KVC。

若要对象支持KVC操作,需要实现NSKeyValueCoding协议,而NSObject已实现该协议,所以OC中几乎所有的对象都支持KVC操作,该协议提供的方法如下:

l  动态设置

setValue:forKey;简单路径

setValue:forKeyPath;复合路径

l  动态读取

valueForKey:

valueForKeyPath:

案例:

//Account类

@interface Account : NSObject

@property(nonatomic,assign)NSInteger balance;//余额

@end

//Person类

    @class Account;

    @interface Person : NSObject

    @property(nonatomic,copy)  NSString * name;

    @property(nonatomic,strong)Account  * account;

@end

 

int main(int argc,const char * argv[])

{

    @autoreleasepool

    {

        Account * account=[[Accountalloc] init];

        Person  * person=[[Personalloc] init];

       

        //KVC

        [person setValue:@"ssl"forKey:@"name"];

        [person setValue:accountforKey:@"account"];

        [person setValue:@12forKeyPath:@"account.balance"];

       

        NSLog(@"name=%@,balance=%ld",person.name,person.account.balance);

    }

    return 0;

}

KVC使用起来比较简单,不管属性是公有的还是私有的,都可以进行读取和设置,但是它如何查找一个属性进行读取或设置呢?(假设对person的name属性进行读取)

l  首先调用setName方法,如果该方法不存在,则搜索成员变量_name,如果属性不存在,则调用setValue:forUndefinedKey:

l  调用name方法,如果没有则搜索_name成员变量,如果成员变量不存在,则调用valueForUndefinedKey;

2、       键值监听KVO

在很多框架中,都支持双向绑定。如果数据模型发生改变,则通知响应的UI更新。在OC中,原生就支持该机制,叫做KeyValue Observing,简称KVO。KVO其实是一种观察者模式,利用它可以很容易实现视图和数据模型的分离,当数据模型发生改变时,作为监听器的视图组件就会被激发进行响应。在OC中要实现KVO必须实现NSKeyValueObserving协议。由于NSObject已实现该协议,因此OC的几乎所有对象都可以使用KVO。

使用KVO的步骤如下:

1)     注册指定key的监听器,addObserver:forKeyPath:option:context:监听器一般为视图组件,而数据模型为监听对象;

2)     实现回调监听:observeValueForKeyPath:ofObject:change:context:

3)     删除指定key的监听器,removeObserver:forKeyPath;

 下面为Account实例的balance属性注册监听器,当balance属性发生改变时,激发监听器响应。

//Account类

@interface Account : NSObject

@property(nonatomic,assign)NSInteger balance;//余额

@end

//Person类

@class Account;

@interface Person : NSObject

@property(nonatomic,copy)  NSString * name;

@property(nonatomic,strong)Account  * account;

@end

 

#import "Person.h"

#import "Account.h"

 

@implementation Person

//注册监听器

-(void) setAccount:(Account *)account

{

    _account=account;

    [_account addObserver:self forKeyPath:@"balance" options:NSKeyValueObservingOptionNew context:nil];

}

//监听

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

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

    {

       NSLog(@" balancechange...");

    }

}

//删除监听器

-(void) dealloc

{

    [_account removeObserver:self forKeyPath:@"balance"];

}

 

@end

 

//主函数

int main(int argc,const char * argv[])

{

    @autoreleasepool

    {

        Account * account=[[Accountalloc] init];

        Person  * person=[[Personalloc] init];

       

        //KVC

        [person setValue:@"ssl"forKey:@"name"];

        [person setValue:accountforKey:@"account"];

        [person setValue:@12forKeyPath:@"account.balance"];

    }

    return 0;

}


原文地址:http://www.cnblogs.com/kenshincui/p/3871178.html 

 

 

 

 

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:35922次
    • 积分:817
    • 等级:
    • 排名:千里之外
    • 原创:48篇
    • 转载:2篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论
  • 图片验证码

    qq_36652294: 楼主,你好,我想问一下,请求到controller之后,前台jap页面怎么接受这个图片并显示呢?我使...

  • 图片验证码

    qq_36652294: 楼主,你好,我想问一下,请求到controller之后,前台jap页面怎么接受这个图片并显示呢?我使...