一、介绍
开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值。在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 ..............................................
本人原创,转载须注明出处,希望对大家有帮助,共同进步!!!