objective-c 回调函数学习(关于objective-c的代理,delegate,protocol相关)
2012-05-24 23:07
495 查看
在Cocoa框架中: 所有的控件、窗口等都继承自 UIView,对应MVC中的 V。UIView及其子类主要负责UI的实现,而UIView所产生的事件都可以采用委托的方式,交给UIViewController实现。对于不同的UIView,都有相应的UIViewController 对应MVC中的C。比如在iPhone OS上常用的UITableView,它所对应的Controller就是UITableViewController。至于MVC中的M,那需要根据用户自己的需求来实现了。 下面看一下一个自定义UIView的架构是怎么样的。这之前要认识一下Objective-C中的几个重要的关键字。 @interface 定义一个类,这个很容易和Java中的interface混淆。 @protocol 定义一个协议,我跟喜欢把它理解成一个接口,相当于Java中的interface。 Objective-C只支持单继承,但可以实现多个协议(接口),语法如下: @interface Child : Parent <Protocol1,Protocol2> { //成员变量定义 } //成员方法,类方法,属性定义 @end 有了以上的知识后,我们就可以来定义自己的UIView了。 首先是定义一个UIView的子类。 @interface MyUIView : UIView { //定义一些控件 id<MyUIViewDelegate> delegate; //这个定义会在后面的解释,它是一个协议,用来实现委托。 } //定义一些控件设置方法 @property id<MyUIViewDelegate> delegate; //定义一个属性,可以用来进行get set操作 @end 然后定义一个Protocol,按照Cocoa的习惯,一般它以delegate结尾,熟悉C#的同学应该知道它的意义。其实不论是接口,委托,还是回调函数,本质上都做了一件事情。就是定义了一个操作契约,然后由用户自己来实现它的具体内容。 @protocol MyUIViewDelegate //这里只需要声明方法 - (void)func1 - (int)func2:(int)arg @end 完成以上两步之后就需要设计自己的UIViewController了。一般简单的做法,可以让这个Controller来实现上面定义的MyUIViewDelegate。在Cocoa框架中,很多控件和它的Controller都是采用的这种方式。 @interface MyUIViewController : UIViewController <MyUIViewDelegate> { //成员变量 } //成员方法,类方法,属性 @end 定义都完成了,到这里其实还看不出这三者是怎么联系起来的。那接下来就要看看,MyUIView和MyUIViewController的具体实现了。 首先是MyUIView的实现代码,假设在MyUIView在发生某个事件后会调用doSometing方法。 - (void)doSomething { if( delegate != nil ) //这里的delegate就是UIView定义时候的一个委托对象 { [delegate func1]; //[]表示对一个对象发消息,如果在Java中会写成delegate.func1() } } 上面的代码中 nil 相当于 Java中的 null,这里的意思就很明显了,如果delegate委托对象不为空,则调用相应的方法,但是这个委托对象的方法在哪里实现呢。可以看一下MyUIViewController的定义,它实现了MyUIViewDelegate。所以这个方法当然是由它来实现。代码如下 - (id)init { MyUIView *myView = [[MyUIView alloc] init]; //对MyUIView进行初始化 myView.delegate = self; //将MyUIViewController自己的实例作为委托对象 self.view = myView; } - (void)func1 { //具体实现,可以加入Model相关的代码 } 这么一来整个,整个代码的线路就明白了。 1.MyUIViewController初始化 2.MyUIViewController初始化时初始化MyUIView,并且将自己作为委托对象赋值给MyUIView 3.MyUIView发生事件,调用(回调)委托对象的方法,其实就是调用MyUIViewController的方法。 再举一个简单的例子: 一个ViewController控制着AView和BView。 现在要实现:AView中点击切换到BView,BView中点击又切换回AView中,并把 Bview删除或隐藏。 由于对模式不是很清楚,所以没想到用什么模式处理,如果有什么好的模式可以 解决上述问题,希望大侠们指教哇。 最后使用的方法是objective-c的代理。 1.在BView.h中定义一个代理: id delegate; // A delegate that wants to act on events in this view 2.定义代理方法,这里使用到的是objective-c 的协议 @interface NSObject ( BViewDelegate) -(void)delegateMethod; @end 注:以上写的协议为非正式的,所以,不用被设置代理者,不实现这个代理方法 也是可以的。 3.在点击中实现代码中,调用代理者实现的代理方法。在BView.m中添加如何类似 代码: //设置了代理者,且代理者实现了delegateMethod if(delegate && [delegate respondsToSelector:@selector(delegateMethod)]) delegate delegateMethod]; 4.在AViem.m中设置BView的代理,并实现delegateMethod方法即可: 类似初始化中添加:[aView setDelegate:self]; -(void)delegateMethod{ //control bView code here ... } 另外,关于正式协议: @protocol protocolName @optional -(void)delegateMethodA @required -(void)delegateMethodB // other methods ... @end 正式协议类似于java的借口或抽象类。@optional 的方法,可实现也可不实现, 但@required 的方法必需实现。默认为@required。 正式协议要求在代理类中声明采纳此代理,如: @interface ClassName: NSObject <ProtocolName> //... @end 另外,在调用特殊代理方法前,需要通过conformsToProtocol函数来判断代理对 象是否遵守定义的协议,如: if([mydelegate conformsToProtocol:@protocol(protocolName)]) { [mydelegate delegateMethod]; } 或者使用respondsToSelector:@selector来判断代理对象是否实现相应的方法。
相关文章推荐
- Objective-C关于协议protocol与代理degelate以及protocol的类型限制
- 第二章、Objective-c 语法,继承,protocol和delegate(iOS学习笔记,从零开始)
- 【初学】Objective-C学习笔记-委托代理(delegate)和协议(protocol)
- iOS 开发-Objective-c基础:协议和代理delegate&protocol)
- 关于delegate(代理,委托)的学习
- objective-c 协议(Protocol)和代理(Delegate)
- iOS监听模式系列之关于delegate(代理,委托)的学习
- 关于delegate(代理)总结
- 学习笔记 - protocol,delegate
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
- Snail—UI学习之代理传值Delegate
- oc中的protocol(协议)与delegate(代理)
- 协议protocol和代理delegate的使用
- 关于委托delegate和协议protocol的讲解
- IOS学习笔记01-关于objective-c的成员属性
- SVN学习笔记10 -- Eclipse中关于SVN 的相关操作
- ruby 元编程 学习记录-关于动态代理
- AppDelegate关于应用程序挂起、复原与终止的代理方法
- protocol(协议) 和 delegate(委托)也叫(代理)---辨析
- Objective-C - protocol学习笔记