加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocoa 键值观察依赖键(KVO)--笔录

发布时间:2020-12-13 22:47:58 所属栏目:百科 来源:网络整理
导读:引子 1. 什么是 键值观察依赖键,可参考文章[深入浅出Cocoa]详解键值观察(KVO)及其实现机理中第4点。 2.由于本人在学习[深入浅出Cocoa]详解键值观察(KVO)及其实现机理过程中,对键值观察依赖键有些不解,固做此笔录。 键值观察依赖键的简单代码实现 我们

引子

1. 什么是键值观察依赖键,可参考文章[深入浅出Cocoa]详解键值观察(KVO)及其实现机理中第4点。

2.由于本人在学习[深入浅出Cocoa]详解键值观察(KVO)及其实现机理过程中,对键值观察依赖键有些不解,固做此笔录。

键值观察依赖键的简单代码实现

我们在上一篇cocoa 自动键值观察(KVO)--笔录 的基础上,对其代码进行修改:


1.添加Other.h 和Other.m文件,目的是想把Other对象的num键作为Target对象age键的依赖键。

//
//  Other.h
//  test_kvo_can_del
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Other : NSObject
@property int num;  //添加变量num,作为依赖键
@end

//
//  Other.m
//  test_kvo_can_del
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import "Other.h"

@implementation Other
@synthesize num;

@end

2.修改Target类

1) 添加other指针,并合成访问器。

//
//  Target.h
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Other.h"

@interface Target : NSObject
@property   int age;  // for auto KVO
@property Other * other; //新添加指针,这个指针必须要有

@end

在被观察者Targer类中添加如下类方法(注意,方法的名字是不固定的),作用是指明依赖关系。即Age属性依赖于other的num属性

<pre name="code" class="objc">//
//  Target.m
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import "Target.h"

@implementation Target
@synthesize age;    // for auto KVO
@synthesize other;

+ (NSSet *)keyPathsForValuesAffectingAge
{
    NSSet * keyPaths = [NSSet setWithObjects:@"other.num",nil]; //注意这里的other.num 写法是严格要求的,名字要与头文件声明的指针other一致!
    return keyPaths;
}

@end


 
 

注:other.num 中的other不是随便写的,是要遵循那个什么KVC-Compliant 规则的, 这里的“other”名字要与头文件声明的"other"指针的名字一致!



3.修改main函数

//
//  main.m
//  AutoKVO
//
//  Created by fenglh on 14-7-31.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Observer.h"
#import "Target.h"
#import "Other.h"
int main(int argc,const char * argv[])
{
    
    @autoreleasepool {
        Observer *observer = [[[Observer alloc] init] autorelease];
<span style="white-space:pre"></span><pre name="code" class="objc" style="font-size: 11px; text-align: left; "><span style="white-space:pre">	</span>Other * other = [[[Other alloc] init] autorelease]; //新增1
Target * target = [[[Target alloc] init] autorelease];
 
<span style="white-space:pre">	</span>//这里用来初始化,target.other的值。最好的办法,我们可以重写Target类的init方法,直接构造对象的时候就初始other的值了。
        target.other = other; //新增2
        [target.other retain];//新增3
        
        
        [target addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:[Target class]];
        //[target setAge:500]; //注释掉原有的
        [other setNum:5000];  //新增4
        [target removeObserver:observer forKeyPath:@"age"];
        
        
    }
    return 0;
}
上面只是新增了4处代码,

1)1是实例化一个other对象

2)2和3只是为了初始化other对象

3)4调用other对象的setNum方法,即修改依赖键num的值


4.运行代码,输出结果:

2014-07-31 07:01:34.839 test_kvo_can_del[28802:303]  >> class : [Target],Age changed
2014-07-31 07:01:34.840 test_kvo_can_del[28802:303]  >> old age is 0
2014-07-31 07:01:34.842 test_kvo_can_del[28802:303]  >> old age is 0

可以看到当我们对other对象的num值进行修改时(注意,我们的被观察者是target而不是other),仍然会触发Observer的observeValueForKeyPath 函数来处理变更通知。

所以,这就是键值观察依赖键的作用了。(至于为什么输出都是0,是随便打印的)


5.小结:

实现键值观察依赖键实现要素:

1)实现keyPathsForValuesAffectingXXXX 的方法,来指明依赖键是那些。

2)在被观察者类Target加入一个指向依赖键所在类Other的指针 ,如Target类中添加:@property Other * other; //新添加指针

3)第2点所说的指针名字“other”要与keyPathsForValuesAffectingXXXX方法里面的other名字一致!否则不遵循KVO-Compliant准则。



注:代码不算完整,只是用来验证键值观察依赖键的实现。应该还有许多不足之处,多多指教。


参考文章:

[深入浅出Cocoa]详解键值观察(KVO)及其实现机理

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读