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 ...
随机推荐
- NTT
1 问题描述FFT问题解决的是复数域上的卷积.如果现在的问题是这样:给出两个整数数列$Ai,Bj,0\leq i\leq n-1,0\leq j\leq m-1$,以及素数$P$,计算新数列$Ci=( ...
- CodeForces 490C Hacking Cypher
Hacking Cypher Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Sub ...
- Java EE 锚、表格用法
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- StopWatch的使用
//StopWatch在System.Diagnostics命名控件,要使用它就要先引用这个命名空间. //其使用方法如下: //var stopWatch = new StopWatch(); // ...
- Shell Sort(草稿)
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Shel ...
- 领域驱动设计系列文章——浅析VO、DTO、DO、PO的概念、区别和用处
本篇文章主要讨论一下我们经常会用到的一些对象:VO.DTO.DO和PO. 由于不同的项目和开发人员有不同的命名习惯,这里我首先对上述的概念进行一个简单描述,名字只是个标识,我们重点关注其概念: 概念: ...
- fFFmpeg 命令、案例、测试集中营
gitbook: https://www.gitbook.com/book/xdsnet/other-doc-cn-ffmpeg/details ffmpeg [全局选项] {[输入文件选项] -i ...
- 流媒体基础实践之——Nginx-RTMP-module 指令详解
转载网址:http://blog.csdn.net/aoshilang2249/article/details/51483814
- oracle dba 职责, 及个人需要掌握内容
ORACLE DBA 职责, 基本相当于日常工作. 0. 数据库设计 1. 模式对象的创建与管理(table, index 等等) 2. 事物管理, 例如并发等 3. SQL 调优 只是针对SQL的 ...
- php三维数组变二维数组
<?php $result = Array(0 => Array(0 => Array(bid => 41,brealname => 'we教官',cid => 4 ...