iOS開發之通過代理逆向傳值

YungFan發表於2017-12-13

在iOS開發中,傳值是幾乎每個App都會用到的,對於傳統的順向傳值應該說是比較簡單的,但是逆向傳值往往會用到代理模式來實現,很多同學在這一塊有迷惑,迷惑的不是怎麼逆向傳值,而是不理解代理模式,下面就來分析一下,如何理解和快速上手代理模式,並以一個簡單的逆向傳值為案例,看看代理模式是不是很難。

一、代理模式中的幾個概念

講代理模式之前,首先需要弄清楚兩個概念:被代理物件代理物件。並且需要知道它們之間是靠協議關連起來的。

1、被代理物件

被代理物件往往就是真正有做事意圖的那個物件,比如賣房子案例中的想賣房子的房主,保姆嬰兒案例中想喝奶的嬰兒。但是它們自己做不到,只能藉助於房產中介和保姆。

2、代理物件

代理物件就是真正辦事的物件,如上面提到的幫賣房子的中介和照顧嬰兒的保姆。

3、協議

代理物件必須有一個規範才能成為代理,比如說只有持證的才能成為房產中介,房主才敢把房子交給他代理,只有家政服務的保姆才敢讓她過來照顧嬰兒,不可能讓保姆去賣房子,讓中介照顧嬰兒。而這個規範就是協議,這個協議誰定的?答案肯定是被代理物件

二、代理模式的書寫規範

弄清楚基本概念以後,接下來就是書寫代理模式,很多同學不知道怎麼下手,其實這也是有跡可循的。

  • 被代理物件
    1、定義協議,在協議中定義方法用於傳值,傳什麼型別的值就設定什麼型別的引數
    2、宣告一個遵守上述協議的delegate屬性
    3、在需要傳值的時候呼叫代理物件完成傳值

  • 代理物件
    1、遵守被代理物件定義的協議
    2、實現協議中的方法,捕獲傳過來的值,並根據需求來處理捕獲的值

  • 設定被代理物件的delegate屬性為代理物件 這一步是在上述兩個物件的其中一個裡面完成的

三、代理模式與逆向傳值

通過如上描述可以看出,其實代理模式只是一種解決特定問題的方法,它有自己的使用場景,比如A想監聽B的一些變化,A無法自己處理某些事情等。俗話說No Code, No BB,下面舉一個實際案例:現在有兩個介面,如圖1圖2所示,介面很簡單,不再贅述,主要是在第一個介面點選跳轉按鈕,到達第二個介面,然後第二介面在輸入框中輸入資訊後點選返回按鈕,第一個介面中的UILabel能顯示第二個介面輸入的內容,這是最簡單的一個逆向傳值。

圖1.png

圖2.png

四、實現步驟

分析: 現在是第二個介面想傳值,但是自己做不了,所以它是被代理物件,第一個介面自然就是代理物件。然後根據上面的規範寫程式碼。

1、被代理物件

//.h 檔案

//被代理物件 做以下幾件事
//1、建立一個協議,用於傳值
//2、宣告一個遵守上述協議的delegate屬性
/**
 *  建立協議,裡面有一個方法,帶一個引數,該引數就是我想傳出去的值
 */
@protocol passValue <NSObject>
-(void)passedValue:(NSString *)inputValue;
@end

@interface NextViewController : UIViewController
/**
 *  宣告一個delegate屬性
 */
@property(nonatomic, weak) id<passValue> delegate;
@end

=================================================================

//.m 檔案
#import "NextViewController.h"

@interface NextViewController ()
@property (weak, nonatomic) IBOutlet UITextField *inputText;
- (IBAction)back:(id)sender;
@end

@implementation NextViewController
- (void)viewDidLoad {
    [super viewDidLoad];  
    self.navigationItem.title = @"第二個介面";
}

/**
 *  返回上一個介面
 *
 *  @param sender <#sender description#>
 */
- (IBAction)back:(id)sender {
    NSString *inputString = self.inputText.text;
    //3、呼叫代理物件完成傳值
    if(self.delegate && [self.delegate respondsToSelector:@selector(passedValue:)]){
        [self.delegate passedValue:inputString];
    }
    [self.navigationController popViewControllerAnimated:YES];
}
@end
複製程式碼

2、代理物件

//.h 檔案

#import <UIKit/UIKit.h>
#import "NextViewController.h"
//代理物件
//實現被代理物件建立的協議,實現其中的方法,捕獲傳過來的值
@interface ViewController : UIViewController <passValue>
@end
=================================================================

//.m 檔案
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *nextPassedValue;
- (IBAction)next:(id)sender;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];  
}

/**
 *  實現被代理物件的方法,將捕獲的值設定到UILabel中
 *
 *  @param inputValue 傳過來的值
 */
-(void)passedValue:(NSString *)inputValue{
    self.nextPassedValue.text = inputValue;
}

//點選返回按鈕跳轉到第二個介面
- (IBAction)next:(id)sender {    
    NextViewController *nvc = [[NextViewController alloc]init];
    //設定被代理物件的delegate屬性為代理物件即self
    nvc.delegate = self;
    [self.navigationController pushViewController:nvc animated:YES];
}
@end
複製程式碼

五、實現效果

逆向傳值.gif

相關文章