博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Objective-C基础笔记(5)Protocol
阅读量:6253 次
发布时间:2019-06-22

本文共 4881 字,大约阅读时间需要 16 分钟。

Protocol简单来说就是一系列方法的列表,其中声明的方法可以被任何类实现。这中模式一般称为代理(delegation)模式。

在IOS和OS X开发中,Apple采用了大量的代理模式来实现MVC中View(UI控件)和Controller(控制器)的解耦。

下面我们先来看一下我们熟悉的Android中的按钮监听过程,然后再对比理解delegation。

首先我建立一个很简单的Android工程,在Layout中放置一个按钮,如下:

package com.example.helloword;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnLongClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button = (Button) findViewById(R.id.mybutton);        button.setOnClickListener(new MyOnClickListener());    }        class MyOnClickListener implements OnClickListener{		@Override		public void onClick(View arg0) {			Toast.makeText(MainActivity.this, 					"点击了按钮", Toast.LENGTH_SHORT).show();		}    }        class MyonLongClickListener implements OnLongClickListener{		@Override		public boolean onLongClick(View arg0) {			Toast.makeText(MainActivity.this, 					"长按了按钮", Toast.LENGTH_SHORT).show();			return false;		}    	    }}
OnClickListener是View的一个内部类,是View定义的一个接口,我们打开OnClickListener源码如下:

/**     * Interface definition for a callback to be invoked when a view is clicked.     */    public interface OnClickListener {        /**         * Called when a view has been clicked.         *         * @param v The view that was clicked.         */        void onClick(View v);    }
我们再来看看setOnClickListener方法

public void setOnClickListener(OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        getListenerInfo().mOnClickListener = l;    }
先判断View是不是可点击的,主要我们来看看下面那一句,getListenerInfo().mOnClickListener = 1;

ListenerInfo getListenerInfo() {        if (mListenerInfo != null) {            return mListenerInfo;        }        mListenerInfo = new ListenerInfo();        return mListenerInfo;    }
从这段代码可以看出来,将我们的OnClickListener实例保存到了ListenerInfor对象中了,那么ListenerInfor对象是用来干嘛的呢?由于我当下没有Android系统源码就不在跟踪下去了,可以猜想这个类持有我们的OnClickeListener对象,当系统响应屏幕点击事件的时候,通过事件分发,可以调用onClick方法来告诉所有实现了OnClickeListener接口的对象。

接下来我们来模拟一下IOS中按钮监听的实现。

Button.h文件

#import 
@class Button;//<>代表实现某个协议//这里相当于OnClickListener@protocol ButtonDelegate
//将Button对象传递给监听器,来判断具体的调用实例- (void) onClick:(Button *)btn;@end@protocol ButtonLongClickDelegate
- (void) onLongClick:(Button *)btn;@end@interface Button : NSObject//delegate就是按钮的监听器//id代表任何OC对象@property (nonatomic, retain) id
delegate;@property (nonatomic, retain) id
longClickDeleate;//模拟系统调用click方法- (void)click;//模拟系统调用longclick方法- (void)longClick;@end
Button.m文件

#import "Button.h"@implementation Button- (void)click {    //按钮被点击了,就应该通知监听器(这里是模拟)    //如果onClick方法被实现,调用onClick方法    if([_delegate respondsToSelector:@selector(onClick:)]){        [_delegate onClick:self];    }else{        NSLog(@"onClick监听器未实现");    }}- (void)longClick {    //按钮被长按(模拟系统)    if([_delegate respondsToSelector:@selector(onClick:)]){        [_longClickDeleate onLongClick:self];    }else{        NSLog(@"longClick监听器未实现");    }}- (void)dealloc {    [_delegate release];    [_longClickDeleate release];    [super dealloc];}@end
ButtonListener.h

#import 
@protocol ButtonDelegate;//实现按钮点击协议@interface ButtonListener : NSObject
@end
ButtonListener.m

#import "ButtonListener.h"#import "Button.h"@implementation ButtonListener- (void)onClick:(Button *)btn {    NSLog(@"按钮被点击了");}@end
ButtonLongClickListener.h文件

#import 
//对协议进行提前声明,跟@class的用途是一样的@protocol ButtonLongClickDelegate;@interface ButtonLongClickListener : NSObject
@end
ButtonLongClickListener.m文件

#import "ButtonLongClickListener.h"#import "Button.h"@implementation ButtonLongClickListener- (void)onLongClick:(Button *)btn{    NSLog(@"按钮被长按了");}@end
main.m文件

#import 
#import "Button.h"#import "ButtonListener.h"#import "ButtonLongClickListener.h"int main(int argc, const char * argv[]) { @autoreleasepool { //初始化一个按钮 Button *button = [[[Button alloc] init] autorelease]; //初始化一个按钮的监听器 ButtonListener *listener = [[[ButtonListener alloc] init] autorelease]; //初始化一个按钮长按监听器 ButtonLongClickListener *longClickListener = [[[ButtonLongClickListener alloc] init] autorelease]; //设置按钮的监听器 button.delegate = listener; //设置长按按钮监听器 button.longClickDeleate = longClickListener; //点击按钮 [button click]; //长按按钮 [button longClick]; } return 0;}
输出结果:

2014-11-16 13:52:35.215 ProtocalTest[845:82273] 按钮被点击了

2014-11-16 13:52:35.216 ProtocalTest[845:82273] 按钮被长按了

转载于:https://www.cnblogs.com/lanzhi/p/6468724.html

你可能感兴趣的文章
#pragma pack(n)
查看>>
IntelliJ IDEA 2018.3 升级功能介绍
查看>>
基于.NET平台常用的框架整理
查看>>
【每天一道算法题】Lucky String
查看>>
整合apache+tomcat+keepalived实现高可用tomcat集群
查看>>
计算几何-HPI
查看>>
香农熵学习+例子[转载]
查看>>
利用DE2上的WM8731D/A转换器产生正弦波
查看>>
清除EasyUi combotree下拉树的值
查看>>
手写RPC框架
查看>>
Hadoop 分片、分组与排序
查看>>
使用Windows8开发Metro风格应用一
查看>>
android尺子的自定义view——RulerView
查看>>
将博客搬至CSDN
查看>>
leetcode43
查看>>
直接在安装了redis的Linux机器上操作redis数据存储类型--set类型
查看>>
016——数组(十六)usort uasort uksort
查看>>
PyQt5+requests实现车票查询工具
查看>>
文件下载界面
查看>>
?:,reverse,vector的基本小结
查看>>