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; @endButton.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> @endButtonListener.m
#import "ButtonListener.h"
#import "Button.h"
@implementation ButtonListener
- (void)onClick:(Button *)btn {
NSLog(@"button被点击了");
}
@endButtonLongClickListener.h文件#import <Foundation/Foundation.h> //对协议进行提前声明,跟@class的用途是一样的 @protocol ButtonLongClickDelegate; @interface ButtonLongClickListener : NSObject <ButtonLongClickDelegate> @endButtonLongClickListener.m文件
#import "ButtonLongClickListener.h"
#import "Button.h"
@implementation ButtonLongClickListener
- (void)onLongClick:(Button *)btn{
NSLog(@"button被长按了");
}
@endmain.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被长按了

浙公网安备 33010602011771号