KVO访问集合属性

使用集合运算符

当您向valueForKeyPath:消息发送符合键值编码的对象时,可以在关键路径中嵌入集合运算符。集合运算符是一个小的关键字列表之一,前面是一个at符号(@),它指定了getter应该执行的操作,以便在返回之前以某种方式操作数据。valueForKeyPath:通过NSObject实现此行为提供的默认实现。

当密钥路径包含集合运算符时,运算符之前的密钥路径的任何部分(称为左键路径)指示相对于消息接收者操作的集合。如果将消息直接发送到集合对象(例如NSArray实例),则可以省略左键路径。

操作符之后的键路径部分(称为右键路径)指定操作员应处理的集合中的属性。除了@count需要正确的密钥路径之外,所有集合运算符。图4-1说明了操作员密钥路径格式。

图4-1操作员密钥路径格式图片:../ Art / keypath.jpg

集合运算符表现出三种基本类型的行为:

  • 聚合运算符以某种方式合并集合的对象,并返回通常与右键路径中指定的属性的数据类型匹配的单个对象。该@count运营商是一个例外,它没有正确的关键路径并始终将返回一个NSNumber实例。

  • 数组运算符返回一个NSArray实例,该实例包含命名集合中保存的对象的某个子集。

  • 嵌套操作符处理包含其他集合的集合,并根据操作符返回一个NSArrayNSSet实例,它以某种方式组合嵌套集合的对象。

样本数据

以下描述包括演示如何调用每个运算符的代码片段,以及执行此操作的结果。这些依赖于BankAccount类,在呈现列表2-1,它保存的阵列Transaction对象。每个代表一个简单的支票簿条目,如清单4-1所示。

清单4-1Transaction对象的接口声明

  1. @interface Transaction : NSObject
  2. @property (nonatomic) NSString* payee; // To whom
  3. @property (nonatomic) NSNumber* amount; // How much
  4. @property (nonatomic) NSDate* date; // When
  5. @end

为了便于讨论,假设您的BankAccount实例有一个使用表4-1中显示的数据填充的事务数组,并且您可以从BankAccount对象内部进行示例调用。

表4-1 Transactions对象的示例数据

payee 值

amount 格式为货币的值

date 格式为月,日的值

Green Power

$120.00

Dec 1, 2015

Green Power

$150.00

Jan 1, 2016

Green Power

$170.00

Feb 1, 2016

Car Loan

$250.00

Jan 15, 2016

Car Loan

$250.00

Feb 15, 2016

Car Loan

$250.00

Mar 15, 2016

General Cable

$120.00

Dec 1, 2015

General Cable

$155.00

Jan 1, 2016

General Cable

$120.00

Feb 1, 2016

Mortgage

$1,250.00

Jan 15, 2016

Mortgage

$1,250.00

Feb 15, 2016

Mortgage

$1,250.00

Mar 15, 2016

Animal Hospital

$600.00

Jul 15, 2016

聚合运算符

聚合运算符可以处理数组或属性集,从而生成反映集合某些方面的单个值。

@avg

指定@avg运算符时,valueForKeyPath:读取集合中每个元素的右键路径指定的属性,将其转换为double(用0代替nil值),并计算这些值的算术平均值。然后它返回存储在NSNumber实例中的结果。

要获得表4-1中的样本数据之间的平均交易金额:

  1. NSNumber *transactionAverage = [self.transactions valueForKeyPath:@"@avg.amount"];

格式化结果transactionAverage为$ 456.54。

@计数

指定@count运算符时,valueForKeyPath:返回NSNumber实例中集合中的对象数。右键路径(如果存在)将被忽略。

获取Transaction对象的数量transactions

  1. NSNumber *numberOfTransactions = [self.transactions valueForKeyPath:@"@count"];

numberOfTransactions是13。

@Max

指定@max运算符时,valueForKeyPath:在右键路径命名的集合条目中搜索并返回最大的一个。搜索使用该compare:方法进行比较,该方法由许多Foundation类(例如NSNumber类)定义。因此,右键路径指示的属性必须包含一个对此消息有意义响应的对象。搜索会忽略nil有价值的集合条目。

要获得表4-1中列出的事务中日期值的最大值(即最新事务的日期):

  1. NSDate *latestDate = [self.transactions valueForKeyPath:@"@max.date"];

格式化的latestDate值是2016年7月15日。

@Min

指定@min运算符时,valueForKeyPath:在右键路径命名的集合条目中搜索并返回最小的一个。搜索使用该compare:方法进行比较,该方法由许多Foundation类(例如NSNumber类)定义。因此,右键路径指示的属性必须包含一个对此消息有意义响应的对象。搜索会忽略nil有价值的集合条目。

要获得表4-1中列出的事务中最小的日期值(即最早的事务日期):

  1. NSDate *earliestDate = [self.transactions valueForKeyPath:@"@min.date"];

格式化的earliestDate值是2015年12月1日。

@和

指定@sum运算符时,valueForKeyPath:读取集合中每个元素的右键路径指定的属性,将其转换为double(将0替换为nil值),并计算这些值的总和。然后它返回存储在NSNumber实例中的结果。

要获得表4-1中样本数据之间的事务数量总和:

  1. NSNumber *amountSum = [self.transactions valueForKeyPath:@"@sum.amount"];

格式化结果amountSum为$ 5,935.00。

数组运算符

数组运算符导致valueForKeyPath:返回与右键路径指示的特定对象集相对应的对象数组。

重要

valueForKeyPath:如果任何叶子对象nil在使用数组运算符时,该方法会引发异常。

@distinctUnionOfObjects

指定@distinctUnionOfObjects运算符时,valueForKeyPath:创建并返回一个数组,该数组包含与右键路径指定的属性对应的集合的不同对象。

要获取payee事务的属性值集合,transactions并忽略重复值:

  1. NSArray *distinctPayees = [self.transactions valueForKeyPath:@"@distinctUnionOfObjects.payee"];

结果distinctPayees数组包含以下每个字符串的一个实例:汽车贷款,通用电缆,动物医院,绿色电力,抵押贷款。

注意

@unionOfObjects运营商提供类似的行为,但没有删除重复的对象。

@unionOfObjects

指定@unionOfObjects运算符时,valueForKeyPath:创建并返回一个数组,该数组包含与右键路径指定的属性对应的集合的所有对象。与@distinctUnionOfObjects不同,不会删除重复的对象。

要获取payee以下事务中的事务的属性值集合transactions

  1. NSArray *payees = [self.transactions valueForKeyPath:@"@unionOfObjects.payee"];

结果payees阵列包含以下字符串:绿色电力,绿色电力,绿色电力,汽车贷款,汽车贷款,汽车贷款,通用电缆,通用电缆,通用电缆,抵押贷款,抵押贷款,抵押贷款,动物医院。请注意重复项。

注意

@distinctUnionOfArrays运营商类似,但删除重复的对象。

嵌套运营商

嵌套运算符对嵌套集合进行操作,集合中的每个条目都包含一个集合。

重要

valueForKeyPath:如果任何叶对象nil在使用嵌套运算符时,该方法会引发异常。

对于下面的描述,考虑第二个数据数组moreTransactions,使用表4-2中的数据填充,并与原始transactions数组(从“ 示例数据”部分)一起收集到嵌套数组中:

  1. NSArray* moreTransactions = @[<# transaction data #>];
  2. NSArray* arrayOfArrays = @[self.transactions, moreTransactions];

表4-2阵列中的假设 Transaction数据 moreTransactions

payee 值

amount 格式为货币的值

date 格式为月,日的值

General Cable - Cottage

$120.00

Dec 18, 2015

General Cable - Cottage

$155.00

Jan 9, 2016

General Cable - Cottage

$120.00

Dec 1, 2016

Second Mortgage

$1,250.00

Nov 15, 2016

Second Mortgage

$1,250.00

Sep 20, 2016

Second Mortgage

$1,250.00

Feb 12, 2016

Hobby Shop

$600.00

Jun 14, 2016

@distinctUnionOfArrays

指定@distinctUnionOfArrays运算符时,valueForKeyPath:创建并返回一个数组,该数组包含与右键路径指定的属性对应的所有集合的组合的不同对象。

payee在以下所有数组中获取属性的不同值arrayOfArrays

  1. NSArray *collectedDistinctPayees = [arrayOfArrays valueForKeyPath:@"@distinctUnionOfArrays.payee"];

结果collectedDistinctPayees数组包含以下值:业余爱好商店,抵押贷款,动物医院,二等抵押贷款,汽车贷款,通用电缆 - 小屋,通用电缆,绿色电力。

注意

@unionOfArrays操作是类似的,但不删除重复的对象。

@unionOfArrays

指定@unionOfArrays运算符时,valueForKeyPath:创建并返回一个数组,该数组包含与右键路径指定的属性对应的所有集合的组合的所有对象,而不删除重复项。

要获取以下payee所有数组中的属性值arrayOfArrays

  1. NSArray *collectedPayees = [arrayOfArrays valueForKeyPath:@"@unionOfArrays.payee"];

结果 collectedPayees数组包含以下值:绿色电力,绿色电力,绿色电力,汽车贷款,汽车贷款,汽车贷款,通用电缆,通用电缆,通用电缆,抵押贷款,按揭贷款,按揭贷款,动物医院,通用电缆 - 小屋,一般电缆 - 小屋,通用电缆 - 小屋,第二按揭,第二按揭,第二按揭,业余爱好商店。

注意

@distinctUnionOfArrays运营商类似,但删除重复的对象。

@distinctUnionOfSets

指定@distinctUnionOfSets运算符时,valueForKeyPath:创建并返回一个NSSet对象,该对象包含与右键路径指定的属性对应的所有集合的组合的不同对象。

此运算符的行为与此类似@distinctUnionOfArrays,只是它需要一个NSSet包含NSSet对象实例而不是NSArray实例实例的NSArray实例。此外,它返回一个NSSet实例。假设示例数据已存储在集合而不是数组中,示例调用和结果与显示的相同@distinctUnionOfArrays

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值