zoukankan      html  css  js  c++  java
  • 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被长按了


  • 相关阅读:
    lua版本的一个状态机
    unity getcomponentsinchildren 翻船
    dotween tips
    ulua c#调用lua中模拟的类成员函数
    洗牌算法
    unity的一些tips
    用Unity写一个12306验证器的恶搞图生成软件
    好久没写Blog了
    蛋疼的时候写三消游戏(十三)
    用DropBox分享Unity3D的Web应用
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4287864.html
Copyright © 2011-2022 走看看