Protocol简单来说就是一系列方法的列表,当中声明的方法能够被不论什么类实现。这中模式一般称为代理(delegation)模式。

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

以下我们先来看一下我们熟悉的Android中的button监听过程,然后再对照理解delegation。

首先我建立一个非常easy的Androidproject,在Layout中放置一个button,例如以下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. android:orientation="vertical" >
  5. <Button
  6. android:id="@+id/mybutton"
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:text="button"/>
  10. </LinearLayout>
  1. package com.example.helloword;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.view.View.OnLongClickListener;
  8. import android.widget.Button;
  9. import android.widget.Toast;
  10.  
  11. public class MainActivity extends Activity {
  12.  
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. Button button = (Button) findViewById(R.id.mybutton);
  18. button.setOnClickListener(new MyOnClickListener());
  19. }
  20.  
  21. class MyOnClickListener implements OnClickListener{
  22.  
  23. @Override
  24. public void onClick(View arg0) {
  25. Toast.makeText(MainActivity.this,
  26. "点击了button", Toast.LENGTH_SHORT).show();
  27. }
  28. }
  29.  
  30. class MyonLongClickListener implements OnLongClickListener{
  31.  
  32. @Override
  33. public boolean onLongClick(View arg0) {
  34. Toast.makeText(MainActivity.this,
  35. "长按了button", Toast.LENGTH_SHORT).show();
  36. return false;
  37. }
  38.  
  39. }
  40. }

OnClickListener是View的一个内部类,是View定义的一个接口,我们打开OnClickListener源代码例如以下:

  1. /**
  2. * Interface definition for a callback to be invoked when a view is clicked.
  3. */
  4. public interface OnClickListener {
  5. /**
  6. * Called when a view has been clicked.
  7. *
  8. * @param v The view that was clicked.
  9. */
  10. void onClick(View v);
  11. }

我们再来看看setOnClickListener方法

  1. public void setOnClickListener(OnClickListener l) {
  2. if (!isClickable()) {
  3. setClickable(true);
  4. }
  5. getListenerInfo().mOnClickListener = l;
  6. }

先推断View是不是可点击的,主要我们来看看以下那一句,getListenerInfo().mOnClickListener = 1;

  1. ListenerInfo getListenerInfo() {
  2. if (mListenerInfo != null) {
  3. return mListenerInfo;
  4. }
  5. mListenerInfo = new ListenerInfo();
  6. return mListenerInfo;
  7. }

从这段代码能够看出来,将我们的OnClickListener实例保存到了ListenerInfor对象中了,那么ListenerInfor对象是用来干嘛的呢?因为我当下没有Android系统源代码就不在跟踪下去了,能够猜想这个类持有我们的OnClickeListener对象,当系统响应屏幕点击事件的时候,通过事件分发,能够调用onClick方法来告诉全部实现了OnClickeListener接口的对象。

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

Button.h文件

  1. #import <Foundation/Foundation.h>
  2. @class Button;
  3.  
  4. //<>代表实现某个协议
  5. //这里相当于OnClickListener
  6. @protocol ButtonDelegate <NSObject>
  7.  
  8. //将Button对象传递给监听器,来推断详细的调用实例
  9. - (void) onClick:(Button *)btn;
  10.  
  11. @end
  12.  
  13. @protocol ButtonLongClickDelegate <NSObject>
  14.  
  15. - (void) onLongClick:(Button *)btn;
  16.  
  17. @end
  18.  
  19. @interface Button : NSObject
  20.  
  21. //delegate就是button的监听器
  22. //id代表不论什么OC对象
  23. @property (nonatomic, retain) id<ButtonDelegate> delegate;
  24. @property (nonatomic, retain) id<ButtonLongClickDelegate> longClickDeleate;
  25.  
  26. //模拟系统调用click方法
  27. - (void)click;
  28.  
  29. //模拟系统调用longclick方法
  30. - (void)longClick;
  31.  
  32. @end

Button.m文件

  1. #import "Button.h"
  2.  
  3. @implementation Button
  4.  
  5. - (void)click {
  6. //button被点击了,就应该通知监听器(这里是模拟)
  7. //假设onClick方法被实现,调用onClick方法
  8. if([_delegate respondsToSelector:@selector(onClick:)]){
  9. [_delegate onClick:self];
  10. }else{
  11. NSLog(@"onClick监听器未实现");
  12. }
  13. }
  14.  
  15. - (void)longClick {
  16. //button被长按(模拟系统)
  17. if([_delegate respondsToSelector:@selector(onClick:)]){
  18. [_longClickDeleate onLongClick:self];
  19. }else{
  20. NSLog(@"longClick监听器未实现");
  21. }
  22. }
  23.  
  24. - (void)dealloc {
  25. [_delegate release];
  26. [_longClickDeleate release];
  27. [super dealloc];
  28. }
  29.  
  30. @end

ButtonListener.h

  1. #import <Foundation/Foundation.h>
  2. @protocol ButtonDelegate;
  3.  
  4. //实现button点击协议
  5. @interface ButtonListener : NSObject <ButtonDelegate>
  6.  
  7. @end

ButtonListener.m

  1. #import "ButtonListener.h"
  2. #import "Button.h"
  3.  
  4. @implementation ButtonListener
  5.  
  6. - (void)onClick:(Button *)btn {
  7. NSLog(@"button被点击了");
  8. }
  9. @end

ButtonLongClickListener.h文件

  1. #import <Foundation/Foundation.h>
  2.  
  3. //对协议进行提前声明,跟@class的用途是一样的
  4. @protocol ButtonLongClickDelegate;
  5.  
  6. @interface ButtonLongClickListener : NSObject <ButtonLongClickDelegate>
  7.  
  8. @end

ButtonLongClickListener.m文件

  1. #import "ButtonLongClickListener.h"
  2. #import "Button.h"
  3.  
  4. @implementation ButtonLongClickListener
  5.  
  6. - (void)onLongClick:(Button *)btn{
  7. NSLog(@"button被长按了");
  8. }
  9.  
  10. @end

main.m文件

  1. #import <Foundation/Foundation.h>
  2. #import "Button.h"
  3. #import "ButtonListener.h"
  4. #import "ButtonLongClickListener.h"
  5.  
  6. int main(int argc, const char * argv[]) {
  7. @autoreleasepool {
  8. //初始化一个button
  9. Button *button = [[[Button alloc] init] autorelease];
  10. //初始化一个button的监听器
  11. ButtonListener *listener = [[[ButtonListener alloc] init] autorelease];
  12. //初始化一个button长按监听器
  13. ButtonLongClickListener *longClickListener =
  14. [[[ButtonLongClickListener alloc] init] autorelease];
  15. //设置button的监听器
  16. button.delegate = listener;
  17. //设置长按button监听器
  18. button.longClickDeleate = longClickListener;
  19. //点击button
  20. [button click];
  21. //长按button
  22. [button longClick];
  23. }
  24. return 0;
  25. }

输出结果:

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

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

Objective-C基础笔记(5)Protocol的更多相关文章

  1. Java基础笔记 – Annotation注解的介绍和使用 自定义注解

    Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Anno ...

  2. php代码审计基础笔记

    出处: 九零SEC连接:http://forum.90sec.org/forum.php?mod=viewthread&tid=8059 --------------------------- ...

  3. MYSQL基础笔记(六)- 数据类型一

    数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...

  4. MYSQL基础笔记(五)- 练习作业:站点统计练习

    作业:站点统计 1.将用户的访问信息记录到文件中,独占一行,记录IP地址 <?php //站点统计 header('Content-type:text/html;charset=utf-8'); ...

  5. MYSQL基础笔记(四)-数据基本操作

    数据操作 新增数据:两种方案. 1.方案一,给全表字段插入数据,不需要指定字段列表,要求数据的值出现的顺序必须与表中设计的字段出现的顺序一致.凡是非数值数据,到需要使用引号(建议使用单引号)包裹. i ...

  6. MYSQL基础笔记(三)-表操作基础

    数据表的操作 表与字段是密不可分的. 新增数据表 Create table [if not exists] 表名( 字段名 数据类型, 字段名 数据类型, 字段n 数据类型 --最后一行不需要加逗号 ...

  7. MYSQL基础笔记(二)-SQL基本操作

    SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...

  8. MYSQL基础笔记(一)

    关系型数据库概念: 1.什么是关系型数据库? 关系型数据库:是一种建立在关系模型(数学模型)上的数据库 关系模型:一种所谓建立在关系上的模型. 关系模型包含三个方面: 1.数据结构:数据存储的问题,二 ...

  9. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  10. JavaScript基础笔记一

    一.真假判断 真的:true.非零数字.非空字符串.非空对象 假的:false.数字零.空字符串.空对象.undefined 例: if(0){ alert(1) }else{ alert(2) } ...

随机推荐

  1. nginx自动切割访问日志

    Web 访问日志 (access_log) 记录了所有外部客户端对Web服务器的访问行为,包含了客户端IP,访问日期,访问的URL资源,服务器返回的HTTP状态码等重要信息. 一条典型的Web访问日志 ...

  2. python urllib和urllib2 区别

    python有一个基础的库叫httplib.httplib实现了HTTP和HTTPS的客户端协议,一般不直接使用,在python更高层的封装模块中(urllib,urllib2)使用了它的http实现 ...

  3. POJ 2104(K-th Number-区间第k大-主席树)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 31790   Accepted: 9838 Cas ...

  4. 简单仿京东导航下拉菜单 javascript

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    ...

  5. C#_会员管理系统:开发四(日志查看)

    新建一个日志查看窗体: 日志需要的登录时间和登录状态信息由用户刚登录程序时就提供,所以在登录窗体(VIPLogin.cs)中添加代码: //定义一个全局变量 Uid; //用于获取登录成功后的用户名 ...

  6. 转化为用欧几里得算法判断互质的问题D - Wolf and Rabbit

    Description There is a hill with n holes around. The holes are signed from 0 to n-1. A rabbit must h ...

  7. 随手记今天跟的几个iOS项目代码的问题

    休了一阵子假期,今天刚回来上班,项目代码已经有挺大的变化了,我就先体验.发现.跟进问题. 第一个问题是点击某个cell就挂掉的现象,同事表示必现但挺神奇.由于挂掉的时候没有啥有意义的信息,所以先简单粗 ...

  8. portal---easyui

    一,效果图. 二,源代码. <!doctype html><html><head> <meta http-equiv="Content-Type&q ...

  9. Oauth1.0认证过程

    现今,已经有了Oauth2.0,写篇博客了解Oauth1.0的过程以及与2.0的区别. 在Oauth官网  关于1.0的介绍: 一.简介 OAuth authentication is the pro ...

  10. 面向对象程序设计-C++ Steam & Vector 【第三次上课笔记】

    大家可以下载后用Vim 或者 Sublime Text等文本编辑器查看 Conference: http://blog.csdn.net/candy1232009/article/details/70 ...