设为首页 加入收藏

TOP

Objective-C基础笔记(5)Protocol
2014-11-23 20:00:06 来源: 作者: 【 】 浏览:14
Tags:Objective-C 基础 笔记 Protocol

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文件

< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD48cHJlIGNsYXNzPQ=="brush:java;">#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; @endButton.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] 按钮被长按了


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇队列的存储结构和常见操作(c 语.. 下一篇uva La 4255 Guess (拓扑排列)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: