Objective-C基础笔记(5)Protocol
Protocol简单来说就是一系列方法的列表,当中声明的方法能够被不论什么类实现。这中模式一般称为代理(delegation)模式。
在IOS和OS X开发中,Apple採用了大量的代理模式来实现MVC中View(UI控件)和Controller(控制器)的解耦。
以下我们先来看一下我们熟悉的Android中的button监听过程,然后再对照理解delegation。
首先我建立一个非常easy的Androidproject,在Layout中放置一个button,例如以下:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <Button
- android:id="@+id/mybutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="button"/>
- </LinearLayout>
- 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,
- "点击了button", Toast.LENGTH_SHORT).show();
- }
- }
- class MyonLongClickListener implements OnLongClickListener{
- @Override
- public boolean onLongClick(View arg0) {
- Toast.makeText(MainActivity.this,
- "长按了button", 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监听的实现。
Button.h文件
- #import <Foundation/Foundation.h>
- @class Button;
- //<>代表实现某个协议
- //这里相当于OnClickListener
- @protocol ButtonDelegate <NSObject>
- //将Button对象传递给监听器,来推断详细的调用实例
- - (void) onClick:(Button *)btn;
- @end
- @protocol ButtonLongClickDelegate <NSObject>
- - (void) onLongClick:(Button *)btn;
- @end
- @interface Button : NSObject
- //delegate就是button的监听器
- //id代表不论什么OC对象
- @property (nonatomic, retain) id<ButtonDelegate> delegate;
- @property (nonatomic, retain) id<ButtonLongClickDelegate> longClickDeleate;
- //模拟系统调用click方法
- - (void)click;
- //模拟系统调用longclick方法
- - (void)longClick;
- @end
Button.m文件
- #import "Button.h"
- @implementation Button
- - (void)click {
- //button被点击了,就应该通知监听器(这里是模拟)
- //假设onClick方法被实现,调用onClick方法
- if([_delegate respondsToSelector:@selector(onClick:)]){
- [_delegate onClick:self];
- }else{
- NSLog(@"onClick监听器未实现");
- }
- }
- - (void)longClick {
- //button被长按(模拟系统)
- if([_delegate respondsToSelector:@selector(onClick:)]){
- [_longClickDeleate onLongClick:self];
- }else{
- NSLog(@"longClick监听器未实现");
- }
- }
- - (void)dealloc {
- [_delegate release];
- [_longClickDeleate release];
- [super dealloc];
- }
- @end
ButtonListener.h
- #import <Foundation/Foundation.h>
- @protocol ButtonDelegate;
- //实现button点击协议
- @interface ButtonListener : NSObject <ButtonDelegate>
- @end
ButtonListener.m
- #import "ButtonListener.h"
- #import "Button.h"
- @implementation ButtonListener
- - (void)onClick:(Button *)btn {
- NSLog(@"button被点击了");
- }
- @end
ButtonLongClickListener.h文件
- #import <Foundation/Foundation.h>
- //对协议进行提前声明,跟@class的用途是一样的
- @protocol ButtonLongClickDelegate;
- @interface ButtonLongClickListener : NSObject <ButtonLongClickDelegate>
- @end
ButtonLongClickListener.m文件
- #import "ButtonLongClickListener.h"
- #import "Button.h"
- @implementation ButtonLongClickListener
- - (void)onLongClick:(Button *)btn{
- NSLog(@"button被长按了");
- }
- @end
main.m文件
- #import <Foundation/Foundation.h>
- #import "Button.h"
- #import "ButtonListener.h"
- #import "ButtonLongClickListener.h"
- int main(int argc, const char * argv[]) {
- @autoreleasepool {
- //初始化一个button
- Button *button = [[[Button alloc] init] autorelease];
- //初始化一个button的监听器
- ButtonListener *listener = [[[ButtonListener alloc] init] autorelease];
- //初始化一个button长按监听器
- ButtonLongClickListener *longClickListener =
- [[[ButtonLongClickListener alloc] init] autorelease];
- //设置button的监听器
- button.delegate = listener;
- //设置长按button监听器
- button.longClickDeleate = longClickListener;
- //点击button
- [button click];
- //长按button
- [button longClick];
- }
- return 0;
- }
输出结果:
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的更多相关文章
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 | 被围观 25,969 views+ 1.Anno ...
- php代码审计基础笔记
出处: 九零SEC连接:http://forum.90sec.org/forum.php?mod=viewthread&tid=8059 --------------------------- ...
- MYSQL基础笔记(六)- 数据类型一
数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...
- MYSQL基础笔记(五)- 练习作业:站点统计练习
作业:站点统计 1.将用户的访问信息记录到文件中,独占一行,记录IP地址 <?php //站点统计 header('Content-type:text/html;charset=utf-8'); ...
- MYSQL基础笔记(四)-数据基本操作
数据操作 新增数据:两种方案. 1.方案一,给全表字段插入数据,不需要指定字段列表,要求数据的值出现的顺序必须与表中设计的字段出现的顺序一致.凡是非数值数据,到需要使用引号(建议使用单引号)包裹. i ...
- MYSQL基础笔记(三)-表操作基础
数据表的操作 表与字段是密不可分的. 新增数据表 Create table [if not exists] 表名( 字段名 数据类型, 字段名 数据类型, 字段n 数据类型 --最后一行不需要加逗号 ...
- MYSQL基础笔记(二)-SQL基本操作
SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...
- MYSQL基础笔记(一)
关系型数据库概念: 1.什么是关系型数据库? 关系型数据库:是一种建立在关系模型(数学模型)上的数据库 关系模型:一种所谓建立在关系上的模型. 关系模型包含三个方面: 1.数据结构:数据存储的问题,二 ...
- JavaScript基础笔记二
一.函数返回值1.什么是函数返回值 函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...
- JavaScript基础笔记一
一.真假判断 真的:true.非零数字.非空字符串.非空对象 假的:false.数字零.空字符串.空对象.undefined 例: if(0){ alert(1) }else{ alert(2) } ...
随机推荐
- nginx自动切割访问日志
Web 访问日志 (access_log) 记录了所有外部客户端对Web服务器的访问行为,包含了客户端IP,访问日期,访问的URL资源,服务器返回的HTTP状态码等重要信息. 一条典型的Web访问日志 ...
- python urllib和urllib2 区别
python有一个基础的库叫httplib.httplib实现了HTTP和HTTPS的客户端协议,一般不直接使用,在python更高层的封装模块中(urllib,urllib2)使用了它的http实现 ...
- POJ 2104(K-th Number-区间第k大-主席树)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 31790 Accepted: 9838 Cas ...
- 简单仿京东导航下拉菜单 javascript
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> ...
- C#_会员管理系统:开发四(日志查看)
新建一个日志查看窗体: 日志需要的登录时间和登录状态信息由用户刚登录程序时就提供,所以在登录窗体(VIPLogin.cs)中添加代码: //定义一个全局变量 Uid; //用于获取登录成功后的用户名 ...
- 转化为用欧几里得算法判断互质的问题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 ...
- 随手记今天跟的几个iOS项目代码的问题
休了一阵子假期,今天刚回来上班,项目代码已经有挺大的变化了,我就先体验.发现.跟进问题. 第一个问题是点击某个cell就挂掉的现象,同事表示必现但挺神奇.由于挂掉的时候没有啥有意义的信息,所以先简单粗 ...
- portal---easyui
一,效果图. 二,源代码. <!doctype html><html><head> <meta http-equiv="Content-Type&q ...
- Oauth1.0认证过程
现今,已经有了Oauth2.0,写篇博客了解Oauth1.0的过程以及与2.0的区别. 在Oauth官网 关于1.0的介绍: 一.简介 OAuth authentication is the pro ...
- 面向对象程序设计-C++ Steam & Vector 【第三次上课笔记】
大家可以下载后用Vim 或者 Sublime Text等文本编辑器查看 Conference: http://blog.csdn.net/candy1232009/article/details/70 ...