重點在通知模式流程圖,大致了解幾種通知模式的用途的區別。都是理論的東西,還是希望實際寫代碼時聯系理論,仔細考慮選擇。
課件下載:
https://github.com/gewill/GeekBand-iOS-Demo/tree/master/Design%20Patterns
6. 委托模式
- 復雜的模型,scrollView,tableView,collectionView
- 單?一個類無法表現復雜的設計
- 設計拆分
- 方便重?
- delegate 獨立對象
- 清晰定義功能,變化行為/自定義界?面
- 松散耦合,容易擴展
以 Master-Detail Application 模板詳細介紹了委托模式。孔老師喜歡直接看類的定義。



7. 觀察者和消息通知


- 定義對象間一種?對多的依賴關系,使得每當一個對象改變狀態,則所有依賴于他的對象都會得到通知并被自動更新。
- Subject被觀察者:定義被觀察者必須實現的職責,它必須能夠動態的增加、取消 觀察者。它一般是抽象類或者是實現類,僅僅完成作為被觀察者必須實現的職責
:管理觀察者并通知觀察者 - Observer觀察者:觀察者接收到消息后,即進行update(更新方法)操作,對接收到的信息進行處理。
- 具體的被觀察者:定義被觀察者自己的業務邏輯,同時定義對哪些事件進行通知。
- 具體的觀察者:每個觀察者在接收到消息后的處理反應是不同的,各個觀察者有自己的處理邏輯。
通知

應用場景:
- 窗口變化通知
- 系統鍵盤的出現和消失/位置?小變化
- UITextField 字符變化通知(可以用來限制輸入長度)
- MPMoviePlayerController 播放器的?為變化(開始結束等事件)
- 自定義Class使用
代碼實現參看李久寧的文章:iOS 設計模式之四:觀察者模式
Key-Value-Coding and Key-Value-Observing
可在 Xcode 中 Open Quickly(??O),查看NSKeyValueCoding.h
協議的內容。
典型的例子 NSOperation and NSOperationQueue
/* NSOperation.h
Copyright (c) 2006-2014, Apple Inc. All rights reserved.
*/
@interface NSOperation : NSObject {
@private
id _private;
int32_t _private1;
#if __LP64__
int32_t _private1b;
#endif
}
- (void)start;
- (void)main;
@property (readonly, getter=isCancelled) BOOL cancelled;
- (void)cancel;
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below
@property (readonly, getter=isAsynchronous) BOOL asynchronous NS_AVAILABLE(10_8, 7_0);
@property (readonly, getter=isReady) BOOL ready;
延伸閱讀:
-
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 集合的深復制與淺復制