KVC 集合操作符
- @count: (NSNumber)集合中对象总数
- @sum: (NSNumber)集合中数值总和
- @avg: (NSNumber)集合中平均数
- @max: 最大值
@min: 最小值
1
2[products valueForKeyPath: @"@count"];
[products valueForKeyPath: @"@sum.price"];@unionOfObjects / @distinctUnionOfObjects: 返回 key path 对应的对象数组,不去重。
@distinctUnionOfObjects
去重。1
[inventory valueForKeyPath: @"@unionOfObjects.name"];
KVO
添加观察者:
1
- addObserver:forKeyPath:options:context:
context
的建议赋值方式是static void *XXContext = &XXContext;
,keyPath
的建议值是@selector(isFinished)
,添加反馈最佳实践如下:1
2
3
4
5
6
7
8
9
10- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (context == XXContext) {
if ([keyPath isEqualToString: NSStringFromSelector(@selector(isFinished))]) {
// ...
}
}
}
NSError
- 错误码(code)一般定义为枚举中的一个常量。
- 用户信息(userInfo)字典中常用的键有:
- localizedDescription
- localizedRecoverySuggestion
- localizedFailureReason
NSError 的用法:
消费者:
1
2
3
4
5
6
7
8NSError *error = nil;
BOOL success = [[NSFileManager defaultManager]
moveItemAtPath:@"/path/to/target"
toPath:@"/path/to/destination"
error:&error];
if (!success) {
NSLog(@"%@", error);
}消除了 Objective-C 方法只有一个返回值的限制。
1
2
3
4
5
6
7
8[[session dataTaskWithRequest:request
completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
// ...
}
}] resume];生产者:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15- (BOOL)validateObject:(id)object
error:(NSError * __autoreleasing *)outError {
// call another API, passing &error into its (NSError **) parameter
NSError *error = nil;
BOOL success = ...;
if (!success) {
if (outError) {
*outError = [NSError errorWithDomain:NSHipsterErrorDomain
code:-42
userInfo:@{NSUnderlyingErrorKey: error}];
}
}
return success;
}
NSOperation
为了让一个 NSOperation 操作开始执行,你可以直接调用-start
,或者将它添加到操作队列 NSOperationQueue 中,添加之后,它会在队列排到它以后自动执行。
NSOperation 的状态机
分为三种状态:isReady —> isExecuting —> isFinished。
NSOperation 的优先级
- NSOperationQueuePriorityVeryHigh
- NSOperationQueuePriorityHigh
- NSOperationQueuePriorityNormal
- NSOperationQueuePriorityLow
- NSOperationQueuePriorityVeryLow
构建依赖关系
1 | [resizingOperation addDependency:networkingOperation]; |
只有networkingOperation
状态isFinished
为YES
, resizingOperation
操作才会开始。
NSSortDescriptor
- key: 对于一个给定的集合,要对每个集合对象进行排序的值的键。
- ascending: YES ascending 表示升序。
- localizedStandardCompare: 根据当前语言环境的规则进行排序。
NSExpression
算数表达式
1 | NSExpression *expression = [NSExpression expressionWithFormat:@"4 + 5 - 2**3"]; |
利用函数
1 | NSArray *numbers = @[@1, @2, @3, @4, @4, @5, @9, @11]; |
支持自定义函数。
统计数字
- average:
- sum:
- count:
- min:
- max:
- median:
- mode:
- stddev:
基本运算
- add:to:
- from:subtract:
- multiply:by:
- divide:by:
- modulus:by:
- abs:
高级运算
- sqrt:
- log:
- ln:
- raise:toPower:
- exp:
边界函数
- ceiling: - (不小于数组中的值的最小整数值)
- trunc: - (最接近但不大于数组中的值的整数值)
NSPredicate
在不可变集合中应用过滤方法,如filteredArrayUsingPredicate:
,那么会返回一个经过过滤的不可变集合。可变集合则直接移除不符合规则的对象。这一过程在内存中进行。
在Core Data
中也能使用NSPredicate
, 只是评估过程由持久化存储助理(persistent store coordinator)在管理对象上下文中(managed object context)进行。
NSCompoundPredicate
NSCompoundPredicate
用于合成现成的NSPredicate
。1
[NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"age > 25"], [NSPredicate predicateWithFormat:@"firstName = %@", @"Quentin"]]];
1 | [NSPredicate predicateWithFormat:@"(age > 25) AND (firstName = %@)", @"Quentin"]; |
以上两段代码功能相同。
Block Predicates
用Block封装任意的运算。1
2
3
4
5NSPredicate *shortNamePredicate = [NSPredicate predicateWithBlock: ^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [[evaluatedObject firstName] length] <= 5;
}];
NSLog(@"Short Names: %@", [people filteredArrayUsingPredicate: shortNamePredicate]);
NSFileManager
通过NSFileManager
的attributesOfItemAtPath:error:
可以访问很多文件的属性,如下的代码得到文件的创建日期:
1 | if ([fileManager fileExistsAtPath:filePath]) { |
如果用一个代理接收关于文件移动、复制、删除等操作的通知,应该创建一个NSFileManager
实例,将代理对象指向 fileManager 的代理。
NSValue
valueWithBytes:objCType:
创建并返回一个包含指定 Objective-C 类型数值的 NSValue 对象。valueWithNonretainedObject:
创建并返回一个包含 Objective-C 对象的 NSValue 对象。这样允许一个对象,在不遵从<NSCopying>
协议的情况下,添加到集合中。
NSValueTransformer
使用 Matt 大神提供的三方库 TransformerKit, 用以下代码注册一个转换字符串首字母大写的NSValueTransformer
:
1 | NSString * const TKCapitalizedStringTransformerName = @"TKCapitalizedStringTransformerName"; |
NS_ENUM & NS_OPTIONS
简单定义NS_ENUM
宏如下:
1 | #ifndef NS_ENUM |
enum 还可以用来定义位掩码。数字二进制的每一位可以看做一个布尔值,用|
和&
进行组合运算。和 NS_ENUM 的语法相同,使用 NS_OPTIONS 宏定义位掩码。
NSCache
- NSCache 实际上是可以自动清理内存空间的 NSMutableDictionary, 而且它的 keys 不用遵从
<NSCopying>
。 - 由于
cost
参数定义不明,尽量不要使用setObject:forKey:cost:
。
NSHashTable & NSMapTable
可以存储弱引用的值,或使用一个没有遵守<NSCopying>
的对象作为键。NSHashTable
对应NSSet
,NSMapTable
对应NSDictionary
。
使NSMapTable
支持对象下标索引,添加以下的 Category 即可:
1 | @implementation NSMapTable (NSHipsterSubscripting) |