Swift: 比較Swift中閉包傳值、OC中的Block傳值


一、介紹

開發者對匿名函數應該很清楚,其實它就是一個沒有名字的函數或者方法,給人直觀的感覺就是只能看到參數和返回值。在iOS開發中中,它又有自己的稱呼,在OC中叫Block代碼塊,在Swift中叫閉包(Closure)函數。在我個人看來,兩者並沒有什么太大不同,定義和實現方式差不多,只不過是名稱不一樣罷了。由於開發用的比較多,所以我就針對OC和Swift分別寫一下他們的傳值方式,加深印象。

 

二、需求

定義兩個控制器分別為FirstViewController和SecondViewController,在FirstViewController中定義閉包或者block,在Push到第二個控制器SecondViewController后,點擊SecondViewController的屏幕觸發閉包或者block,打印閉包或者block傳遞過來的值。

 

三、步驟

  • 聲明閉包或者block別名
  • 定義閉包或者block屬性
  • 定義觸發閉包的函數/方法
  • 定義傳值的函數/方法

 

四、測試

1、Swift:閉包Closure

FirstViewController.swift

import UIKit

/**
 *  聲明一個閉包別名,閉包含字符串類型的兩個參數,無返回值(使用“()”或者“Void”都一樣)
 */
typealias SwiftClosure = (name:String,age:Int) -> Void

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()
        
     //創建push按鈕 let button
= UIButton.init(frame: CGRectMake(200, 200, 100, 100)) button.setTitle("Push", forState: .Normal) button.center = self.view.center button.backgroundColor = UIColor.greenColor() button.setTitleColor(UIColor.redColor(), forState: .Normal) button.addTarget(self, action: #selector(PushSecondViewController), forControlEvents: .TouchUpInside) self.view.addSubview(button) } /** * 定義閉包屬性,可選類型 */ var callBackClosure = SwiftClosure?() /** * 定義觸發閉包調用的方法,此時需要將要傳遞的參數存入閉包中 * 此處我將參數固定死了,開發中根據需要自己可以將需要的數值當做方法的參數,其實就是給方法添加參數即可,由外部決定參數值 * 例如: func TriggerClosure(name:String,age:Int) -> Void { } */ func TriggerClosure(){ if callBackClosure != nil { callBackClosure!(name:"夏遠全",age:26) } } /** * 閉包觸發調用后,對閉包屬性賦值,同時提供調用外部訪問閉包中數值的接口 */ func callBackClosureFunction(closure:SwiftClosure){ callBackClosure = closure } /** * Push第二個控制器入棧 */ func PushSecondViewController() -> Void { self.navigationController?.pushViewController(SecondViewController(), animated: true) } }

SecondViewController.swift

import UIKit

class SecondViewController: UIViewController {

    /**
     *  創建第一個控制器實例
     */
    let firstVC = FirstViewController()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.purpleColor()
        
        /**
         * 接收閉包觸發后回傳的數值並打印
         */
        firstVC.callBackClosureFunction { (name, age) in
            print("name:\(name), age:\(age)")
        }
    }
    
    /**
     *  點擊屏幕觸發閉包
     */
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        firstVC.TriggerClosure()
    }
    
}

點擊演示結果如下,每一次點擊都會觸發閉包打印數據:

name:夏遠全, age:26
name:夏遠全, age:26
name:夏遠全, age:26
name:夏遠全, age:26
..................

 

 

2、OC:Block代碼塊

FirstViewController.h

#import <UIKit/UIKit.h>

/**
 *  聲明一個block別名,block含字符串類型的兩個參數,無返回值
 */
typedef void (^OCBlock)(NSString *name,NSInteger age);

@interface FirstViewController : UIViewController

/**
 *  觸發block
 */
-(void)TriggerBlock;

/**
 *  block回調
 */
-(void)callBackBlockFunction:(OCBlock) block;

@end

FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"



@interface FirstViewController ()
/**
 *  定義block屬性
 */
@property (copy,nonatomic)OCBlock callBackBlock;
@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
 
    //創建push按鈕
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
    [button setTitle:@"Push" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor redColor]];
    [button addTarget:self action:@selector(PushSecondViewController) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

/**
 *  Push第二個控制器入棧
 */
-(void)PushSecondViewController{
    [self.navigationController pushViewController:[[SecondViewController alloc] init] animated:YES];
}

/**
 *  定義觸發block調用的方法,此時需要將要傳遞的參數存入block中
 *  此處我將參數固定死了,開發中根據需要自己可以將需要的數值當做方法的參數,其實就是給方法添加參數即可,由外部決定參數值
 *  例如:-(void)TriggerBlock(name:String,age:Int) { }
 */
-(void)TriggerBlock{
    
    if (self.callBackBlock) {
        self.callBackBlock(@"夏遠全",26);
    }
}

/**
 *  block觸發調用后,對block屬性賦值,同時提供調用外部訪問block中數值的接口
 */
-(void)callBackBlockFunction:(OCBlock) block{
    self.callBackBlock = [block copy];
}


@end

SecondViewController.m

#import "SecondViewController.h"
#import "FirstViewController.h"

@interface SecondViewController ()
/**
 *  創建第一個控制器實例
 */
@property (strong,nonatomic)FirstViewController *firstVC;
@end

@implementation SecondViewController

-(void)viewDidLoad{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    
    
    _firstVC = [[FirstViewController alloc] init];
    
    /**
     * 接收block觸發后回傳的數值
     */
    [_firstVC callBackBlockFunction:^(NSString *name, NSInteger age) {
        NSLog(@"name:%@  age:%ld",name,age);
    }];
    
}

/**
 *  點擊屏幕觸發Block
 */
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [_firstVC TriggerBlock];
}

@end

點擊演示結果如下,每一次點擊都會觸發閉包打印數據:

2017-01-06 17:51:19.814 閉包[26322:355426] name:夏遠全  age:26
2017-01-06 17:51:27.837 閉包[26322:355426] name:夏遠全  age:26
2017-01-06 17:51:28.037 閉包[26322:355426] name:夏遠全  age:26
2017-01-06 17:51:28.221 閉包[26322:355426] name:夏遠全  age:26
2017-01-06 17:51:28.405 閉包[26322:355426] name:夏遠全  age:26
..............................................

 

本人原創,轉載須注明出處,希望對大家有幫助,共同進步!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM