KVC与KVO的进阶使用
本篇主要介绍键-值编码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的进阶使用的更多相关文章
- 聊聊 KVC 和 KVO 的高阶应用
KVC, KVO 作为一种魔法贯穿日常Cocoa开发,笔者原先是准备写一篇对其的全面总结,可网络上对其的表面介绍已经够多了,除去基本层面的使用,笔者跟大家谈下平常在网络上没有提及的KVC, KVO进阶 ...
- 11. KVC And KVO
1. KVC And KVO 的认识 KVC/KVO是观察者模式的一种实现 KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...
- iOS - 详细理解KVC与KVO
详细理解KVC与KVO 在面试的时候,KVC与KVO有些时候还是会问到的,并且他们都是Objective C的关键概念,在这里我们先做一个简单地介绍: (一)KVC: KVC即指:NSKeyValue ...
- KVC 与 KVO 理解
KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一 ...
- 【原】iOS中KVC和KVO的区别
在iOS开发中经常会看到KVC和KVO这两个概念,比较可能混淆,特地区分一下 KVC(Key Value Coding) 1> 概述 KVC:Key Value Coding,键值编码,是一种间 ...
- IOS之KVC和KVO(未完待续)
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- KVC和KVO的区别
kvc和kvo 1.kvc Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性.KVO 就 ...
- 谈KVC、KVO(重点观察者模式)机制编程
一不小心,小明在<跟着贝尔去冒险>这个真人秀节目中看到了“一日警察,一世警察”的Laughing哥,整个节目除了贝尔吃牛睾丸都不用刀叉的不雅餐饮文化外,还是镜头少普通话跟小明一样烂的Lau ...
- iOS中关于KVC与KVO知识点
iOS中关于KVC与KVO知识点 iOS中关于KVC与KVO知识点 一.简介 KVC/KVO是观察者模式的一种实现,在Cocoa中是以被万物之源NSObject类实现的NSKeyValueCodin ...
随机推荐
- Bootstrap_基本HTML模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- 对 strcpy_s 若干测试
今天发现如果strcpy这函数,目标buffer太小,会有意想不到的崩溃.而且不容易调试.以后尽量要用strcpy_s了. strcpy_s是strcpy的更安全的版本 1.当目标字符串参数是一个字符 ...
- CentOS 7下编译FreeSWITCH 1.6
安装背景: 已经最小化安装CentOS 7. 准备工作: 挂载安装光盘,配置yum本地化安装,配置方法可以参考http://www.cnblogs.com/yoyotl/p/4877439.html. ...
- unity3d中asset store 的资源下载到本地的目录位置
来源:http://blog.csdn.net/fzhlee/article/details/8613688 C:/Users/[当前用户]/AppData/Roaming/Unity/Asset S ...
- 委托、匿名方法、Lambda表达式的演进
摘自:"http://www.cnblogs.com/eagle1986/archive/2012/01/19/2327358.html 假设给我们一个泛型对象List<T>,T ...
- web工程中各类地址写法的总结
首先打一个"/" //如果地址给服务器用,那么"/"就代表该web应用 , 如果给浏览器用的,那么"/"就代表网站(其下有多个web应用) ...
- Java Abstract class and Interface
Abstract Class 在定义class的时候必须有abstract 关键字 抽象方法必须有abstract关键字. 可以有已经实现的方法. 可以定义static final 的常量. 可以实现 ...
- ZOJ-2338 The Towers of Hanoi Revisited 输出汉诺塔的最优解移动过程
题意:给定N(1<= N <=64)个盘子和M(4<= M <= 65)根柱子,问把N个盘子从1号柱子移动到M号柱子所需要的最少步数,并且输出移动过程. 分析:设f[i][j] ...
- Switch用法
package com.cz.test; public class SwitchExample1 { /** * @param args */ public static void main(Stri ...
- HTML5探索之datalist研究
最近一个项目需要用到类似淘宝,百度搜索时的自动检索方案.自然想到了使用datalist标签.但是遇到一个bug,经过两天研究.小有结果给大家分享下~~ 首先看bug吧!~ 因为项目最开始测试就是用36 ...