一、介紹
開發者對匿名函數應該很清楚,其實它就是一個沒有名字的函數或者方法,給人直觀的感覺就是只能看到參數和返回值。在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 ..............................................
本人原創,轉載須注明出處,希望對大家有幫助,共同進步!!!