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 ...
随机推荐
- FreeSWITCH第三方库(音频)的简单介绍(一)
FreeSWITCH使用了大量的第三方库,本文档主要介绍音频相关库的信息: 视频相关库的信息介绍参考:http://www.cnblogs.com/yoyotl/p/5488890.html 其他相关 ...
- Javascript this指针
Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象. 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对 ...
- SqlServer 存储过程分页
适用于2005以上版本 create procedure [dbo].[SP_GetPageList] ( @columns nvarchar(max), --查询字段 @tablename nvar ...
- C#强制清除缓存
#region 强制清除缓存 [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize" ...
- [转]产品需求文档(PRD)的写作
产品需求对产品研发而言非常重要,写不好需求,后面的一切工作流程与活动都会受到影响.转载一篇文章,关于产品需求文档写作方面的,如下: 本文摘自(一个挺棒的医学方面专家):http://www.cnblo ...
- css position 绝对定位和相对定位
position:absolute这个是绝对定位:是相对于浏览器的定位.比如:position:absolute:left:20px;top:80px; 这个容器始终位于距离浏览器左20px,距离浏览 ...
- maven实现依赖的“全局排除”
大多数java应用源码构建和依赖管理是使用maven来实现的,maven也是java构建和依赖管理的事实上的标准.我们的应用系统也都是基于maven构建的,maven虽然在依赖管理方面确实很牛叉,但是 ...
- [转]-Gradle使用手册(二):项目结构
原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Using-sourceCompatibility-1. ...
- [转载]bigtable 中文版
转载厦门大学林子雨老师的译文 原文: http://dblab.xmu.edu.cn/post/google-bigtable/ Google Bigtable (中文版) 林子雨2012-05-08 ...
- Promise A 规范的一个简单的浏览器端实现
简单的实现了一个promise 的规范,留着接下来模块使用.感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码 主要是Then 函数.回调有点绕人. !(function(win) { fu ...