本篇主要介绍键-值编码KVC,键值观察KVO的进阶使用的一些技巧主要是一下两个方面:

  • KVC的集合操作符
  • KVO的手动实现方式

KVC集合操作符

关于集合操作符在苹果官方文档搜索Collection Operators的关键字就可以查看相关的文档。建议多看官方文档,本篇介绍也是以官方文档为基础的。

如果一个对象包含一个数组或者是集合的属性那么使用valueForKeyPath获取相关的属性时可以在键的路径中插入一些函数。这些函数称为集合操作符

按照分类可以分为三类:

  • 简单的集合操作符

    • @avg
    • @count
    • @max
    • @min
    • @sum
  • 对象操作符

    • @distinctUnionOfObjects
    • @unionOfObjects
  • 数组和集合操作符

    • @distinctUnionOfArrays
    • @unionOfArrays
    • @distinctUnionOfSets

对于这些操作符使用的格式如下:

现在声明一个自定义的对象如下:

@interface TestModel : NSObject
@property (nonatomic,strong) NSString *title;
@property (nonatomic,strong) NSString *detail;
@property (nonatomic,strong) NSArray *strings;
-(instancetype)init;
@end @implementation TestModel
- (instancetype)init
{
self = [super init];
if (self) {
_title = @"title";
_detail = @"detail";
_strings = @[@{
@"number":@"2"
},
@{
@"number":@"3"
},
@{
@"number":@"4"
},
@{
@"number":@"5"
},
@{
@"number":@"1"
},
@{
@"number":@"1"
}];
}
return self;
}
@end

首先声明一个TestModel类型的属性

@property (nonatomic,strong) TestModel *testModel; 

@avg:遍历集合中的元素将它们转换为一个双精度浮点数并返回表示它们的平均数NSNumber类型的对象

    _testModel = [[TestModel alloc] init];
id object = [self valueForKeyPath:@"testModel.strings.@avg.number"];
NSLog(@"object--%@\nclass--%@",object,[object class]);

输出:

object--2.73333333333333333333333333333333333333
class--NSDecimalNumber

@count:返回集合中对象的数量

     _testModel = [[TestModel alloc] init];
id object = [self valueForKeyPath:@"testModel.strings.@count"];
NSLog(@"object--%@\nclass--%@",object,[object class]);

输出:

object--6
class--__NSCFNumber

@max与@min:返回集合中的最大值与最小值

     _testModel = [[TestModel alloc] init];
id object = [self valueForKeyPath:@"testModel.strings.@max.number"];
NSLog(@"object--%@\nclass--%@",object,[object class]);
_testModel = [[TestModel alloc] init];
id object = [self valueForKeyPath:@"testModel.strings.@min.number"];
NSLog(@"object--%@\nclass--%@",object,[object class]);

输出:

object--5
class--__NSCFConstantString
object--1
class--__NSCFConstantString

@sum:遍历集合中的每一项将它们转换为一个双精度浮点数并返回表示它们的和NSNumber类型的对象

@distinctUnionOfObjects:返回集合中所有的对象如果有相同的对象那么只返回一个。

     _testModel = [[TestModel alloc] init];
id object = [self valueForKeyPath:@"testModel.strings.@distinctUnionOfObjects.number"];
NSLog(@"object--%@\nclass--%@",object,[object class]);

输出:

object--(
3,
5,
1,
4,
"2.4"
)
class--__NSArrayI

数组中属性number为1的值有两个此时只返回一个。


@unionOfObjects:与@distinctUnionOfObjects相反,返回所有的对象包括重复的对象。


@distinctUnionOfArrays、@unionOfArrays、@distinctUnionOfSets与上述使用方法大致相同只不过操作对象由数组里的对象变成数组里的集合。


KVO的手动实现方式

如果我们使用KVO时不想更改某个属性时立刻回调,比如更改一个属性后想要执行某个操作,这个操作执行后才希望通过收到通知那么此时就需要手动实现KVO监听。

我们手动实现KVO首先要禁用系统自带的KVO监听,禁用的方法非常简单在想要监听的对象实现automaticallyNotifiesObserversForKey并返回NO即可。对于上面的自定义模型在其内部实现以下方法来达到当title属性发生变化时不会收到通知:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
{
if ([key isEqualToString:@"title"]) {
return NO;
}
else
return YES;
}

手动实现KVO也是通过调用willChangeValueForKey与didChangeValueForKey这两个基类方法实现的。

     _testModel = [[TestModel alloc] init];
[_testModel addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL]; _testModel.title = @"chapter";

上面的写法因为禁用了title属性的自动监听功能所以当title发生变化时系统不会监听到。

     _testModel = [[TestModel alloc] init];
[_testModel addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL]; [_testModel willChangeValueForKey:@"title"];
_testModel.title = @"chapter";
// do something
[_testModel didChangeValueForKey:@"title"];

调用didChangeValueForKey时系统才会监听到title已经发生变化

KVC与KVO的进阶使用的更多相关文章

  1. 聊聊 KVC 和 KVO 的高阶应用

    KVC, KVO 作为一种魔法贯穿日常Cocoa开发,笔者原先是准备写一篇对其的全面总结,可网络上对其的表面介绍已经够多了,除去基本层面的使用,笔者跟大家谈下平常在网络上没有提及的KVC, KVO进阶 ...

  2. 11. KVC And KVO

    1. KVC And KVO  的认识 KVC/KVO是观察者模式的一种实现  KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...

  3. iOS - 详细理解KVC与KVO

    详细理解KVC与KVO 在面试的时候,KVC与KVO有些时候还是会问到的,并且他们都是Objective C的关键概念,在这里我们先做一个简单地介绍: (一)KVC: KVC即指:NSKeyValue ...

  4. KVC 与 KVO 理解

    KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一 ...

  5. 【原】iOS中KVC和KVO的区别

    在iOS开发中经常会看到KVC和KVO这两个概念,比较可能混淆,特地区分一下 KVC(Key Value Coding) 1> 概述 KVC:Key Value Coding,键值编码,是一种间 ...

  6. IOS之KVC和KVO(未完待续)

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  7. KVC和KVO的区别

    kvc和kvo 1.kvc Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性.KVO 就 ...

  8. 谈KVC、KVO(重点观察者模式)机制编程

    一不小心,小明在<跟着贝尔去冒险>这个真人秀节目中看到了“一日警察,一世警察”的Laughing哥,整个节目除了贝尔吃牛睾丸都不用刀叉的不雅餐饮文化外,还是镜头少普通话跟小明一样烂的Lau ...

  9. iOS中关于KVC与KVO知识点

    iOS中关于KVC与KVO知识点 iOS中关于KVC与KVO知识点  一.简介 KVC/KVO是观察者模式的一种实现,在Cocoa中是以被万物之源NSObject类实现的NSKeyValueCodin ...

随机推荐

  1. 向sql server 导入数据库

    在sql server 中选择数据库.右键,还原数据库 选择源设备,点击添加,选中相应的数据库文件. 在目标数据库栏选择相应的数据库名称 点击下一步.

  2. c#扩展方法的理解(一:初识)

    扩展方法是静态方法,是类的一部分,但是实际上没有放在类的源代码中. 扩展方法所在的类也必须被声明为static C#只支持扩展方法,不支持扩展属性.扩展事件等. 扩展方法的第一个参数是要扩展的类型,放 ...

  3. LINUX DIFF命令详解

    刚才在和公司做离线IP对比,最后手工了,感觉还是比较麻烦的,遇到数据很大的时候不能手工进行了 本想用linux下的DIFF来进行对比,发现结果很乱.时间很紧最后还是手工了. 现在忙完要认认真真学习一下 ...

  4. dup2()函数的使用,

    #define STR "xiamanman\n"#define STR_LEN 10#define STDOUT 1 #include <stdio.h>#inclu ...

  5. [SAP ABAP开发技术总结]客户端文本文件、Excel文件上传下载

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. python_way day14 CSS

    python_way day14 CSS 层叠样式表 一.CSS作用域: 二.css标签选择器 三.css样式 一.css作用域: 基本用法:style="样式" <body ...

  7. Sbt的使用初步和用sbt插件生成eclipse工程

    以前一直是用maven去管理java项目,现在开始写scala项目了但是在scala-ide中去编译scala项目和sbt的区别一直没弄清楚受到文章:http://my.oschina.net/yjw ...

  8. AJAX 简介

    什么是 AJAX ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味 ...

  9. fFFmpeg 命令、案例、测试集中营

    gitbook: https://www.gitbook.com/book/xdsnet/other-doc-cn-ffmpeg/details ffmpeg [全局选项] {[输入文件选项] -i ...

  10. 流媒体基础实践之——RTMP直播推流

    一.RTMP推流:用户可将RTMP视频流推送到阿麦提供的打流地址.地址格式类似于: rtmp://livepush.myqcloud.com/live 现在可以支持哪些直播源?和那些直播软件?推流参数 ...