Objective-C基礎筆記(5)Protocol,objectivec編程

來源:互聯網
上載者:User

Objective-C基礎筆記(5)Protocol,objectivec編程

Protocol簡單來說就是一系列方法的列表,其中聲明的方法可以被任何類實現。這中模式一般稱為代理(delegation)模式。

在IOS和OS X開發中,Apple採用了大量的代理模式來實現MVC中View(UI控制項)和Controller(控制器)的解耦。

下面我們先來看一下我們熟悉的Android中的按鈕監聽過程,然後再對比理解delegation。

首先我建立一個很簡單的Android工程,在Layout中放置一個按鈕,如下:

<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="按鈕"/></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{@Overridepublic void onClick(View arg0) {Toast.makeText(MainActivity.this, "點擊了按鈕", Toast.LENGTH_SHORT).show();}    }        class MyonLongClickListener implements OnLongClickListener{@Overridepublic 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檔案

#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就是按鈕的監聽器//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 {    //按鈕被點擊了,就應該通知監聽器(這裡是類比)    //如果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 <Foundation/Foundation.h>@protocol ButtonDelegate;//實現按鈕點擊協議@interface ButtonListener : NSObject <ButtonDelegate>@end
ButtonListener.m

#import "ButtonListener.h"#import "Button.h"@implementation ButtonListener- (void)onClick:(Button *)btn {    NSLog(@"按鈕被點擊了");}@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(@"按鈕被長按了");}@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 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] 按鈕被長按了


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.