KVO模式

本文介绍了Objective-C中键值编码(KVC)的基本原理及应用,并深入探讨了键值观察(KVO)的实现方法,展示了如何利用这两种技术进行属性访问和观察。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇主要从使用上讲解一下KVO

其实如果要用KVO必须先理解KVC,KVC就是键值编码

举个例子:

我们定义一个类,person

@interface Person : NSObject
{

    NSString * name;
}
@property(nonatomic, retain)NSString * name;
@end

@implementation Person
@synthesize name;


@end

那么最简单的访问该类属性name的方法,是什么,很简单

无论附值还是访问,我们都采用person.name 访问

Person * person = [[Person alloc] init];
    person.name = @"123";
    NSLog(@"person %@",person.name);

那么还有其他方式附值还是访问,答案是肯定的

看对他改动:

@interface Person : NSObject
{
@public
    NSString * name;
}
//@property(nonatomic, retain)NSString * name;
@end

 Person * person = [[Person alloc] init];
 person->name = @"123";
 NSLog(@"%@",person->name);

此时我将变量公布出来,所以可以采用指针访问,

那么,我们看看KVC访问吧

@interface Person : NSObject
{
    @private
    NSString * name;
}

Person * person = [[Person alloc] init];
    [person setValue:@"123" forKey:@"name"];
    NSLog(@"%@",[person valueForKey:@"name"]);
KVC包括了附值和访问,就算声明成类的是有变量,也无法阻止对于变量的访问和附值,可以看出对于KVC来说已经不存在私有变量一说了,都可以用键访问。

原理,就摘抄一下,

KVC运用了一个isa- swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa- swizzling,来实现其内部查找定位的。
isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

比如说如下的一行KVC的代码:

[site setValue:@"sitename" forKey:@"name"];
就会被编译器处理成:

SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (site->isa,sel);
method(site, sel, @"sitename", @"name");
首先介绍两个基本概念:

(1)SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

(2)IMP数据 类型:他其实就是一个编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型(事实上,在Objective-C的编译器处理的时候,基本上都是C语言的)。
这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候,
(1)首先根据方法名找到运行方法的时候所需要的环境参 数。
(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。
(3)再直接查找得来的具体的方法实现。

至于KVO,那就更简单了,明白了KVC,KVO就是为了观察某个属性诞生的,使用方法:

 Person * person = [[Person alloc] init];
    person.name = @"123";
    [person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
    person.name = @"234";

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"old: %@ new:%@",[change objectForKey:@"old"],[change objectForKey:@"new"]);
    }
}

2014-03-26 10:57:29.765 KVCdemo[32716:a0b] old: 123 new:234

好了,这里基本就明白如何使用了,对于观察以及及时刷新界面是很强大的哦~~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值