你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS開發——使用delegate進行消息傳遞

iOS開發——使用delegate進行消息傳遞

編輯:IOS開發綜合

iOS開發中,界面之間傳遞消息或者數據是最基本的一種需求,我們可以使用很多方法來實現這種需求,比如在頭文件中暴露一個屬性、比如使用notification等等。今天我們要來介紹另一種方式:使用delegate傳遞消息。

delegate稱為委托,同時也是一種代理設計模式。使用委托避免了類與類的耦合度過高。利用委托賦值更加安全可控,委托賦值在不暴露自己類的屬性的前提下就可以對自己進行賦值。

在iOS中委托通過協議@protocol來實現,在協議中所聲明的方法,不需要在協議中有實現的方法,是由它的實現類來實現(該類需要在頭文件中包含<協議名>)。“協議”和“委托”是兩個不一樣的概念,因為我們在看代碼的時候總是會看到他們出現在一起。但不能說,delegate就是protocol,delegate是一種架構模式。舉個例子什麼是“委托”:比如我在開車,但是開車不能看短信,所以我就叫車裡的朋友幫我看短信,這樣我就可以正常的開車了。當朋友看完短信內容後,就告訴我是什麼內容。這就是委托,朋友就是我的委托對象。“協議”protocol是用來定義對象的屬性和行為,類似於C++中的虛函數。其中有兩個關鍵字@required和@optional,前者表示必須要實現的方法,後者是可選的方法。

使用delegate常用在兩種情況下:

*兩個類之間的傳值,類A調用類B的方法,類B在執行過程中遇到問題通知類A;

*控制器(ViewController)與控制器(ViewController)之間的傳值,從A跳轉到B,再從B返回到A時需要通知A更新UI或者是做其他的事情,這時候就用到了代理(delegate)傳值。

tips:如果沒有在@protocol中顯式的寫上@required或者@optional,那麼默認就是@required(必需的)的。為了不引起歧義,最好顯式的寫上@required或@optional。

通常一個delegate的使用過程需要經過5步:

(1)創建一個delegate;

(2)委托者聲明一個delegate;

(3)委托者調用delegate內的方法(method);

(4)被委托者設置delegate,以便被委托者調用;

(5)被委托者實現delegate所定義的方法;

下面我通過1個實例來演示使用delegate傳遞數據,代碼上傳至:https://github.com/chenyufeng1991/iOS-Delegate 中的Delegate01.

(1)首先程序是基於storyboard來構建的,界面布局如下:在界面返回的時候將會傳遞數據。

\

 

(2)新建一個Protocol,作為我們的協議,裡面可以聲明一些方法。如圖:

\

 

 

ProtocolDelegate裡面的實現如下:

 

#import 

//實現一個protocol;
/**
 *  可以理解為Java中的接口interface;
 */
@protocol ProtocolDelegate 

// 必須實現的方法
@required
- (void)execute;

// 可選實現的方法
@optional
- (void)function1;
- (void)function2;
- (void)function3;

@end


 

(3)我首先來實現第二個界面,在第二個界面的頭文件.h中需要聲明一個protocol,在該protocol中聲明的方法可以在第一個界面中實現,並在第二個界面中進行調用。這是數據傳遞的關鍵。

 

#import 

// 新建一個協議,協議的名字一般是由“類名+Delegate”
/**
 *  在該協議中聲明的方法,在第一個界面中實現,在該界面中調用;
 */
@protocol ViewControllerBDelegate 

@required
- (void)sendValue:(NSString *)value;

@end

@interface ViewControllerB : UIViewController

//這裡的delegate要設置在.h中;
@property (weak, nonatomic) id delegate;

@end

(4)在第二個界面的實現文件中實現如下:在點擊返回鍵的時候調用協議中的方法,

 

 

#import "ViewControllerB.h"

//第二個界面;
@interface ViewControllerB ()

@property (strong, nonatomic) IBOutlet UITextField *textField;

@end

@implementation ViewControllerB

- (IBAction)backAction:(id)sender{

  //界面跳轉的時候調用該方法;
  [self.delegate sendValue:self.textField.text]; // 通知執行協議方法
  //返回傳遞消息;
  [self.navigationController popViewControllerAnimated:YES];
}

@end

(5)下面來實現第一個界面ViewController.m:

 

 

#import "ViewController.h"
#import "ProtocolDelegate.h"
#import "ViewControllerB.h"

//第一個界面;
@interface ViewController () 

@end

@implementation ViewController

//因為是基於storyboard的segue來構建,當界面跳轉時,自動回調該方法;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    ViewControllerB *vc = segue.destinationViewController;
    [vc setDelegate:self];

}

// 這裡實現B控制器的協議方法
- (void)sendValue:(NSString *)value{
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"成功" message:value delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
    [alertView show];
}

//該方法是ProtocolDelegate中的@required方法;
- (void)execute{
    
}


- (IBAction)pressed:(id)sender {

  NSLog(@"1111");

}


@end

(6)運行效果如下:

 

\

 

\

 

上面的demo是基於storyboard。由於有些項目是基於nib文件構建的,我下面來演示一下使用nib文件時的注意點。

(1)刪除原來的main.storyboard,新增兩個nib文件,分別綁定對應的ViewController。我推薦使用navigationBar,所以在AppDelegate.m中的實現如下:

 

#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {



  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  self.window.rootViewController = [[ViewController alloc] init];

  self.naviController = [[UINavigationController alloc] initWithRootViewController:self.window.rootViewController];

  [self.window addSubview:self.naviController.view];
  [self.window makeKeyAndVisible];


  return YES;
}

@end

(2)在第二個界面中主要修改如下,刪除prepareForSegue方法,在按鈕的點擊方法中實現:

 

 

- (IBAction)pressed:(id)sender {
  //如果項目本身是根據nib文件構建的,就使用下面的方式綁定delegate,並跳轉;
  ViewControllerB *vb    = [[ViewControllerB alloc] initWithNibName:@"ViewControllerB" bundle:[NSBundle mainBundle]];
  vb.delegate            = self;

  [self.navigationController pushViewController:vb animated:true];

}

 

然後運行效果同上。不同之處也就是在ViewController綁定delegate處有不同。

 

總結,Delegate委托屬於程序架構層面上,是相對比較高的層次,如果我們能夠熟練使用delegate,就能有效降低程序耦合度,提高代碼可讀性。!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved