极客班 iOS 设计模式(二)
重点在通知模式流程图,大致了解几种通知模式的用途的区别。都是理论的东西,还是希望实际写代码时联系理论,仔细考虑选择。
课件下载:
https://github.com/gewill/GeekBand-iOS-Demo/tree/master/Design%20Patterns
6. 委托模式
- 复杂的模型,scrollView,tableView,collectionView
- 单⼀一个类无法表现复杂的设计
- 设计拆分
- 方便重⽤
- delegate 独立对象
- 清晰定义功能,变化行为/自定义界⾯面
- 松散耦合,容易扩展
以 Master-Detail Application 模板详细介绍了委托模式。孔老师喜欢直接看类的定义。
NSOperationQueue延伸阅读:
-
Apple Key-Value Coding Programming Guide
This document describes the NSKeyValueCoding informal protocol, which defines a mechanism allowing applications to access the properties of an object indirectly by name (or key), rather than directly through invocation of an accessor method or as instance variables.
Dot Syntax and Key-Value Coding: Objective-C’s dot syntax and key-value coding are orthogonal technologies. You can use key-value coding whether or not you use the dot syntax, and you can use the dot syntax whether or not you use KVC. Both, though, make use of a “dot syntax.” In the case of key-value coding, the syntax is used to delimit elements in a key path. Remember that when you access a property using the dot syntax, you invoke the receiver’s standard accessor methods.
-
我们会常常提及“接收者”和“发送者”。它们在消息传递中的意思可以通过以下的例子解释:一个 table view 是发送者,它的 delegate 就是接收者。Core Data managed object context 是它所发出的 notification 的发送者,获取 notification 的就是接收者。一个滑块 (slider) 是 action 消息的发送者,而实现这个 action (方法)的是它的接收者。任何修改一个支持 KVO 的对象的对象是发送者,这个 KVO 对象的观察者就是接收者。明白精髓了吗?
基于不同消息传递机制的特点的流程图
communication-patterns-flow-chart
9. 归档和解档
NSCoding
是一个简单的协议,有两个方法: -initWithCoder: 和 encodeWithCoder:。遵循NSCoding协议的类可以被序列化和反序列化,这样可以归档到磁盘上或分发到网络上。
@interface Book : NSObject <NSCoding>
@property NSString *title;
@property NSString *author;
@property NSUInteger pageCount;
@property NSSet *categories;
@property (getter = isAvailable) BOOL available;
@end
@implementation Book
#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
self.title = [decoder decodeObjectForKey:@"title"];
self.author = [decoder decodeObjectForKey:@"author"];
self.pageCount = [decoder decodeIntegerForKey:@"pageCount"];
self.categories = [decoder decodeObjectForKey:@"categories"];
self.available = [decoder decodeBoolForKey:@"available"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.title forKey:@"title"];
[encoder encodeObject:self.author forKey:@"author"];
[encoder encodeInteger:self.pageCount forKey:@"pageCount"];
[encoder encodeObject:self.categories forKey:@"categories"];
[encoder encodeBool:[self isAvailable] forKey:@"available"];
}
@end
NSKeyedArchiver 和 NSKeyedUnarchiver
提供了很方便的API把对象读取/写入磁盘。一个基于NSCoding的table view controller可以通过file manager设置它的属性集合。
[NSKeyedArchiver archiveRootObject:books toFile:@"/path/to/archive"];
[NSKeyedUnarchiver unarchiveObjectWithFile:@"/path/to/archive"];
NSUserDefaults
每个应用程序都有自己的user preferences,它可以存储和检索遵循NSCoding协议的对象或者是C类型数据。
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:books];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"books"];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"books"];
NSArray *books = [NSKeyedUnarchiver unarchiveObjectWithData:data];
延伸阅读:
10. 复制模式
- 创建一个对象的新副本
- 复制一个复杂对象时,保护一个一样的对象,还是包含原来对象的副本
- 用户界面上的复制/粘贴 有些对象封装了独一无⼆的资源,复制没有意义
- 浅复制和深复制。顾名思义,浅复制,并不拷⻉对象本⾝,仅仅是拷贝指向对象的指针;深复制是直接拷贝整个对象内存到另⼀块内存中
- initWithDictionary:copyItems
就是个典型例子,可深可浅。
参看 MicroCai 的文章:iOS 集合的深复制与浅复制