`
icheng
  • 浏览: 833265 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
文章分类
社区版块
存档分类
最新评论

Objective-C学习之路 委托模式

 
阅读更多

Objective-C学习之路 委托模式

Objective-C学习之路 委托模式是本文要介绍内容,委托模式很重要,比如官方交互API,委托模式使用的很常见,比如UIView的setAnimationDelegate,设置动画的委托。不理解委托模式,就不能很快的理解很多API的使用,因为它们使用一样的模式,了解这个模式,就会心领神会,立即上手。

下面用通俗的话说说委托模式是干什么用的。实际上Objective-C中的委托模式,类似于Java中的回调(CallBack)机制,或者说监听器机制。再或者说,类似JavaScript语言里面的onclick事件和函数的作用。比如要实现点击一个按钮之后做什么事情,这里肯定有个视图类,有个控制类,无论你是使用什么语言和开发工具。视图类能知道用户什么时候点击了按钮,但是不知道点击了以后做什么,控制类知道点击按钮后做什么,而不知道何时用户会点击。那么,可以将控制类委托给视图类,当点击的时候视图类调用控制类。

如果使用过Java的Swing等做本地图形界面开发,应该知道在视图类中包含了大量的(匿名)内部类,或者要注册监听器,这些机制起到和Objective-C委托类似的功效。可以这样理解:监听器、(匿名)内部类是实现怎么做的部分,但是不知道何时会发生事情,视图类在事件发送时调用监听器、(匿名)内部类,视图类是知道何时发生事情的。

写个简单的示例,是在main方法里写的,模拟一下委托在视图和控制中的作用。这里面,我有一个屏幕(Screen)类,就把它当视图吧。需求是当点击屏幕的时候爆炸。那么我有个动作(Action)类,它会实现爆炸动作。

用协议实现委托模式

下面的代码写的很生硬,后面会逐渐演化为合理的实现。第一个示例只是想说明技术上如何实现,没有实际运用上的意义。

这里因为是模拟,可以把main方法看作是用户再操作界面,通过点击创建了个视图(Screen),然后调用Screen的实例方法onTouch,这里模拟用户用手点击了屏幕:

  1. #import<Foundation/Foundation.h>
  2. #import"Screen.h"
  3. intmain(intargc,constchar*argv[]){
  4. NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
  5. Screen*screen=[[Screenalloc]init];
  6. screenscreen.delegate=screen;
  7. [screenonTouch];
  8. [screenrelease];
  9. [pooldrain];
  10. return0;
  11. }

这里先不用管:

  1. screenscreen.delegate=screen;

后面再说。

Action类,在这里用协议来实现:

  1. #import<Cocoa/Cocoa.h>
  2. @protocolAction<NSObject>
  3. -(void)doAction;
  4. @end

是一个协议,该协议继承了NSObject协议。这里要注意,NSObject在这里不是类,确实有同名类。这个协议定义了一个doAction方法,这个方法可实现比如“屏幕爆炸”的需求。

下面说说屏幕(Screen)类,头文件:

  1. #import<Foundation/Foundation.h>
  2. #import"Action.h"
  3. @interfaceScreen:NSObject<Action>{
  4. id<Action>delegate;
  5. }
  6. @property(nonatomic,retain)id<Action>delegate;
  7. -(void)onTouch;
  8. @end

这里的onTouch方法,就是模拟Screen被用户点击后调用的方法。Screen类实现了Action协议。然后它还有个Action类型的成员delegate。为了能设置delegate实例变量,还为它设置了property。

下面看看实现文件:

  1. #import"Screen.h"
  2. @implementationScreen
  3. @synthesizedelegate;
  4. -(void)onTouch{
  5. NSLog(@"ontouch…");
  6. if([delegateconformsToProtocol:@protocol(Action)]&&
  7. [delegaterespondsToSelector:@selector(doAction)]){
  8. [delegateperformSelector:@selector(doAction)];
  9. }
  10. NSLog(@"ontouched.");
  11. }
  12. -(void)doAction{
  13. NSLog(@"Bang!!!!!!!!!");
  14. }
  15. @end

这里重点看onTouch方法内部代码,要判断delegate是否是Action协议,而且是否有doAction方法,这个判断够严谨了。如果正确,就调用Action协议的doAction方法。

实际上未必要让Screen实现Action协议,虽然开发中经常是类似这样的做法。任意的实现Action协议的类实例都可以设置给screen的delegate属性。

上面的示例和开发中碰到的情况不很像,实际情况往往类似下面示例的样子。首先看看main方法:

  1. #import<Foundation/Foundation.h>
  2. #import"MyScreen.h"
  3. intmain(intargc,constchar*argv[]){
  4. NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
  5. Screen*screen=[[MyScreenalloc]init];
  6. [screenonTouch];
  7. [screenrelease];
  8. [pooldrain];
  9. return0;
  10. }

这里发现增加了个MyScreen 类。它继承自Screen类。这里的代码不再设置delegate属性,因为已经在MyScreen类的init方法中设置了。后面会看到。

Action协议没有变化,只是增加了optional:

  1. #import<Cocoa/Cocoa.h>
  2. @protocolAction<NSObject>
  3. @optional
  4. -(void)doAction;
  5. @end

Screen类,可以看作抽象类,它主要供继承使用,来复用委托模式的代码。头文件:

  1. #import<Foundation/Foundation.h>
  2. #import"Action.h"
  3. @interfaceScreen:NSObject<Action>{
  4. id<Action>delegate;
  5. }
  6. @property(nonatomic,retain)id<Action>delegate;
  7. -(void)onTouch;
  8. @end

实现文件:

  1. #import"Screen.h"
  2. @implementationScreen
  3. @synthesizedelegate;
  4. -(void)onTouch{
  5. NSLog(@"ontouch…");
  6. if([delegateconformsToProtocol:@protocol(Action)]&&
  7. [delegaterespondsToSelector:@selector(doAction)]){
  8. [delegateperformSelector:@selector(doAction)];
  9. }
  10. NSLog(@"ontouched.");
  11. }
  12. @end

这里不再实现doAction方法。

下面看MyScreen类的头文件:

  1. #import<Cocoa/Cocoa.h>
  2. #import"Screen.h"
  3. @interfaceMyScreen:Screen{
  4. }
  5. @end

MyScreen类的实现文件:

  1. #import"MyScreen.h"
  2. @implementationMyScreen
  3. -(id)init{
  4. if(self=[superinit]){
  5. delegate=self;
  6. }
  7. returnself;
  8. }
  9. -(void)doAction{
  10. NSLog(@"Bang!!!!!!!!!");
  11. }
  12. @end

用类别实现委托模式

可以使用类别(Category)实现委托模式。还是上面的例子。下面使用Category实现了个示例。

main方法:

  1. intmain(intargc,constchar*argv[]){
  2. NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
  3. Screen*screen=[[Screenalloc]init];
  4. [screenonTouch];
  5. [screenrelease];
  6. [pooldrain];
  7. return0;
  8. }

Screen类的头文件:

  1. #import<Foundation/Foundation.h>
  2. @interfaceScreen:NSObject{
  3. iddelegate;
  4. }
  5. @property(nonatomic,retain)iddelegate;
  6. -(void)onTouch;
  7. @end

在这个示例中,实际上property没有起什么作用。

实现文件:

  1. #import"Screen.h"
  2. @implementationScreen
  3. @synthesizedelegate;
  4. -(id)init{
  5. if(self=[superinit]){
  6. delegate=self;
  7. }
  8. returnself;
  9. }
  10. -(void)onTouch{
  11. NSLog(@"ontouch…");
  12. if([delegaterespondsToSelector:@selector(doAction)]){
  13. [delegateperformSelector:@selector(doAction)];
  14. }
  15. NSLog(@"ontouched.");
  16. }
  17. @end

写到这里,如果运行代码,只会打印类似下面的日志:

  1. 2011-05-2610:37:30.843DelegateDemo[5853:a0f]ontouch…
  2. 2011-05-2610:37:30.846DelegateDemo[5853:a0f]ontouched.

下面写Category代码,名称为ScreenAction,它的头文件:

  1. #import<Cocoa/Cocoa.h>
  2. #import"Screen.h"
  3. @interfaceScreen(ScreenAction)
  4. -(void)doAction;
  5. @end

实现文件:

  1. #import"ScreenAction.h"
  2. @implementationScreen(ScreenAction)
  3. -(void)doAction{
  4. NSLog(@"BANG!!!!!!");
  5. }
  6. @end

实现了这部分代码再执行:

  1. 2011-05-2610:37:30.843DelegateDemo[5853:a0f]ontouch…
  2. 2011-05-2610:37:30.846DelegateDemo[5853:a0f]BANG!!!!!!
  3. 2011-05-2610:37:30.846DelegateDemo[5853:a0f]ontouched.

小结:Objective-C学习之路 委托模式的内容介绍完了,希望本文对你有所帮助。

<!--leftbotcon end-->
分享到:
评论

相关推荐

    Objective-C编程之道IOS设计模式解析pdf文档及源码

    Objective-C编程之道IOS设计模式解析pdf文档及源码,精心整理全套

    Objective-C委托的例子程序

    一个演示如何使用Objective-C中协议和委托的例子程序,使用到了单例、观察者等设计模式。

    Google Objective-C Style Guide 中文版

    Google Objective-C Style Guide 中文版 目录 例子 空格与格式 空格与制表符 行宽 方法声明与定义 方法调用 @public与@private 异常 ...Objective-C++ ...Objective-C方法名 ...委托模式 模型-视图-控制器

    OBJECTIVE-C编程之道 IOS设计模式解析电子书+源代码

    OBJECTIVE-C编程之道 IOS设计模式解析电子书+源代码《Objective-C编程之道:iOS设计模式解析》是基于iOS的软件开发指南。书中应用GoF的经典设计模式,介绍了如何在代码中应用创建型模式、结构型模式和行为模式,...

    Using Swift with Cocoa and Objective-C完整中文CocoaChina精校版

    Objective Objective Objective Objective-C选择器 选择器 (Selectors)(Selectors)(Selectors) (Selectors)(Selectors)(Selectors)(Selectors) 15 2.2. 2.2. 使用 Objective Objective Objective Objective-C特性...

    UsingDelegates:iOS Objective-C,实现委托设计模式

    委托设计模式的解释和实现 问:1什么是委托设计模式? 答:1“委派是一种简单而强大的模式,其中应用程序中的一个对象代表另一个对象或与另一个对象协同工作。委派对象在适当的时候保留对另一个对象(委托)的引用...

    iosStudy:Objective-C和iOS研究

    iosStudy1_UIViewExample UIView UIImageView ViewController2_ProtocolDelegateExample @协议委托模式@property弱属性(保留周期问题)3_TableViewExample UITableView UITableViewCell UITableViewDataSource ...

    iPhone应用开发从入门到精通代码

    C语言与C++混用975.4 本章小结985.5 本章练习98第6章 iPhone程序的设计模式996.1 MVC模式996.2 对象共享模式1016.3 目标和动作模式1046.4 通告模式1056.5 归档模式1076.6 子视图模式1086.7 委托模式1106.8...

    HysteriaPlayer:Objective-C音频播放器,位于AVPlayer之上

    用很少的块设置HysteriaPlayer,在UIView和UIViewController子类中实现委托,以在播放器事件发生更改时更新UI。 能够推进下一个/上一个项目。 如果播放器由于缓冲问题而暂停播放,请在缓冲大小达到5秒后自动恢复...

    cocoa基本原理指南

    2. "Cocoa对象" 解释Objective-C的基本用法和优点,以及 Cocoa对象的常见行为、接口、和生命周期。 3. "为Cocoa程序添加行为" 描述如何使用Cocoa框架来编写程 序,解释如何创建一个子类。 4. "Cocoa的设计模式" 描述...

    block-party:乐高委托模式。 阻止 FTW!

    乐高委托模式。 去授权化 使用 Block Party 将所有委托回调替换为块(或者只是一些 - 在所有情况下仍会触发委托回调)。 核心蓝牙(CBCentralManager、CBPeripheral 和 CBPeripheralManager) 外设管理器 [ self ....

    Cocoa基本原理指南(2010年4月16日).zip

    2. "Cocoa对象" 解释Objective-C的基本用法和优点,以及 Cocoa对象的常见行为、接口、和生命周期。 3. "为Cocoa程序添加行为" 描述如何使用Cocoa框架来编写程 序,解释如何创建一个子类。 4. "Cocoa的设计模式" 描述...

    resume:我的在线简历

    较强的代码阅读能力和语言学习能力理解并能熟练运用iOS应用开发中常见设计模式,如:MVC、委托、广播、单例等熟练使用CocoaTouch基础框架:Foundation 、UIKit、CoreGraphics、AVFoundation、Mapkit等掌握Core Data...

    WebSockets开发包starscream.zip

    starscream 是使用 Swift 实现了 iOS 和 OS X 的 Websockets(RFC 6455)。 同时还有个 Objective-C 版本的:jetfire ... 简单的委托模式设计 TLS/WSS 支持 几百行简单的 LOC 代码 标签:starscream

    ua-aws-sdk-ios:适用于Amazon Web Services(AWS)的iOS SDK

    适用于iOS的AWS开发工具包(未签名的应用程序版本) 这是的到Objective-C的端口。 它旨在(最终)扩大对适用于iOS的正式AWS开发工具包的覆盖范围,并改进队列和块用于处理响应的用法。 注意:这是预发行软件,因此...

    LocationManager:在iOS上轻松获取设备的当前位置

    INTULocationManager可以轻松获取设备的当前位置,并且当前正在iOS上运行。 这是一个Objective-C... CLLocationManager使用更传统的委托模式,而不是现代的基于块的回调模式。 尽管跟踪用户位置随时间的变化效果很好

    WillzPlotz_iOS:来自 Yahoo! 的股票报价数据的简单图iOS 财务

    WillzPlotz - 获取股票价格并使用 CoreGraphics 进行可视化 这个项目演示了我用 Objective-C 开发的 iOS 数据可视化框架,称为 iViz。 该框架为折线图和条形图提供了基本视图控制器,可以使用委托协议模式对其进行...

    TwitterAPI封装Objectwitter-C.zip

    在 STTwitter 对 Twitter REST API 的全面封装的基础上,增添了很多工具类使得 API 更加抽象,易用,并且完全重新设计了 Twitter Streaming API 的封装,利用类似于 NSURLSession/NSURLConnection 的委托模式...

    驾校管理系统毕业设计源码-resume:恢复

    能够使用Objective-C、Swift进行iOS应用开发,了解C/C++,python 等编程语言 熟练使用Storyboard/Xib 进行界面设计和布局,使用AutoLayout进行屏幕适配,掌握各种UI控件的使用和自定义 掌握MVC,委托代理等常用设计...

    《iOS6开发指南》精彩书摘

    本书是智捷iOS课堂团队编写iOS系列丛书中的一本,目的是使一个有Objective-C基础的程序员通过本书的学习,能够从零基础到在App Store发布一款应用。全书分为4篇:  第一部分基础篇,介绍了iOS一些基础的知识。 第1...

Global site tag (gtag.js) - Google Analytics