程序运行时,程序中的各个实例必定会交互,互相影响状态。这个在我们起初设计的时候,就会考虑进去。于是就必须使用一种比较妥当的方式,在对象之间传递消息。这些消息可能是一些变量、常量,也可能是一个事件,比如下载完成。我这几天在coding的时候,发现自己原先一直用的定义public变量的方法实在太土太无语。于是仔细研究了一下objective-c中对象之间传递信息的方法。发现委托机制非常不错。
委托机制,字面理解就是找个委托人来做一些事情。比如我有一个下载类(定义为WizDownload),他的主要功能是负责与服务器交互,下载数据。但是下载完成后数据怎么处理就不是这个类负责了(这符合单一职责原则),是由另外一个类负责(WizDownloadViewController)。那怎样在这两个类之间传递下载完成的消息呢。我曾经用到的有这么几种方案:
一。定义public变量。在WizDownload中定义一个(id)Owner和SEL,在事件发生后,调用owner的SEL。
1 @interface WizDownload :NSObject 2 { 3 id owner; 4 SEL selector; 5 } 6 ........... 7 8 - (void) downloadDone 9 { 10 [owner selector]; 11 }
但是这种反感充满了腐臭味,完全破坏了类结构,如果有一个类要继承WizDownload,完全没有必要继承这两个变量。从另一方面讲这样做代码量也十分大。
二、使用NSNotification机制。在WizDownloadViewController中注册监听下载完成消息。然后在WizDownload下载完成后发送一个下载完成的消息。
#define WizDownloadDoneMessage @"WizDownloadDoneMessage" //WizDownloadViewController - (void) downloadDone { ....... } - (id) init { ... [ [NSNotificationCenter defaultCenter] addobserver:self selector:@selector(downloadDone).......]; ... } //WizDownload - (void) downloadDone { [[NSNotificationCenter defaultCenter] postMessage......]; }
这样代码完全没有结构。只是依靠一个消息机制来控制程序的行为,而且,如果另外一个对象意外的也这册了这个消息。就会引发不必要的行为。所以这种方案也并不是很好。
三、下面说到的就是主角——委托机制了。
委托机制是Objective-C中一种常用的模式。主要使用的技术是协议。使用下面的代码来说明更合适一点。这样的结构清晰明了。
1 @protocol WizDownloadDelegate 2 - (void) downloadDone; 3 @end 4 5 @interface WizDownload : NSObject 6 { 7 id <WizDownloadDelegate> delegate; 8 } 9 @property (retain) id <WizDownloadDelegate> delegate; 10 @end 11 12 @implement WizDownload 13 - (void) wizDownloadDone 14 { 15 ..... 16 [delegate downloadDone]; 17 ..... 18 } 19 @end 20 21 22 @interface WizDownloadController :NSObject <WizDownloadDelegate> 23 ...... 24 @end 25 26 @implement WIzDownloadController 27 - (void) downloadDone 28 { 29 ..... 30 } 31 @end