一、介绍

开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值。在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:
name:夏远全, age:
name:夏远全, age:
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(, , , )];
[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(@"夏远全",);
}
} /**
* 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

点击演示结果如下,每一次点击都会触发闭包打印数据:

-- ::19.814 闭包[:] name:夏远全  age:
-- ::27.837 闭包[:] name:夏远全 age:
-- ::28.037 闭包[:] name:夏远全 age:
-- ::28.221 闭包[:] name:夏远全 age:
-- ::28.405 闭包[:] name:夏远全 age:
..............................................

本人原创,转载须注明出处,希望对大家有帮助,共同进步!!!

Swift: 比较Swift中闭包传值、OC中的Block传值的更多相关文章

  1. Swift 闭包即OC中的Block

    - 闭包的定义 1.提前准备好的代码        2.在需要的时候执行        3.可以当做参数传递 // 1.最简单的闭包 // () -> () 没有参数,没有返回值的函数 // 如 ...

  2. swift中闭包的学习。

    在swift中的闭包等同于OC中的block,它的用途就是在于可以包装一段代码在必要的时候进行调用. 闭包定义:  {(类型列表) -> 返回值 in // 多条swift语句 // 执行代码 ...

  3. Swift基础--Swift中的异常处理

    Swift中的异常处理 OC中的异常处理:方法的参数要求传入一个error指针地址,方法执行完后,如果有错误,内部会给error赋值 Swift中的异常处理:有throws的方法,就要try起来,然后 ...

  4. Swift 基础部分(建议掌握OC字符串知识的翻阅)

    更新说明: Swift 目前已经发布到4.0版本了,以前写的这整个Swift学习系列的文章,有很多的不足之处,我会重新整理整个系列文章,也是相当于重新复习一遍Swift,后面系列文章的改动之处全都会做 ...

  5. OC中并发编程的相关API和面临的挑战

    OC中并发编程的相关API和面临的挑战(1) 小引 http://www.objc.io/站点主要以杂志的形式,深入挖掘在OC中的最佳编程实践和高级技术,每个月探讨一个主题,每个主题都会有几篇相关的文 ...

  6. swift中闭包的循环引用

    首先我们先创造一个循环引用 var nameB:(()->())? override func viewDidLoad() { super.viewDidLoad() let bu = UIBu ...

  7. iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法

    1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...

  8. Swift: 在Swift中桥接OC文件(自己创建的类文件、第三方库文件)

    一.介绍 随着Swift的逐渐成熟,使用swift开发或者混合开发已经成为了一个趋势,本身苹果公司也十分推荐使用Swift这门新语言.目前Swift已经更新到了3.0,估计没有多久4.0就要出来了.那 ...

  9. 如何在swift中实现oc中的分类

    在oc中为了增强已有类的功能,我们经常使用分类.使用分类,我们可以在不破坏原有类的结构的前提下,对原有类进行模块化的扩展. 但是在swift中没有分类这种写法了.相对应的是swift中只有扩展(Ext ...

随机推荐

  1. navigation和tabbar上的文字.图片 自定义

    [[UITabBarItem appearance] setTitleTextAttributes:@{ UITextAttributeTextColor : [UIColor blackColor] ...

  2. Ubuntu防火墙设置

    转载自:http://baisongfly.blog.163.com/blog/static/30135117200923005956159/ 1.安装 sudo apt-get install uf ...

  3. 1.0 Quartz 2D 简介

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书”   Quartz2D须知:   (1)Quartz 2D是苹果官方的二维绘图引擎,同时支持 ...

  4. [MySQL]使用Begin...End语句的一个坑

    写一个触发器,执行单条语句是OK的. 想执行多条语句,尝试在代码中加入BEGIN END.但一加BEGIN END就报错, 错误信息也很诡异,只说某一行出错了,不符合Mysql的语句规范,提示信息就个 ...

  5. mysql缓存、存储引擎

    一.         mysql查询缓存 查询缓存不是mysql的子系统,却是查询优化和执行子系统不可缺少的组成部分.它不仅可以缓存查询结果,还可以缓存查询结果本身.如果某个查询的结果就在缓存里, 系 ...

  6. Java 异常java.lang.IllegalArgumentException: Illegal group reference

    当字符串方法replaceAll()中替换字符含有特殊字符$如, String test = "<StreamingNo>abc</StreamingNo>" ...

  7. 利用box-shadow绘图

    上篇博客提到过,box-shadow属性的本质是对形状的复制,那么如果我设置一个1*1px的i标签,利用box-shadow可以叠加的特性,给每一个1*1px的阴影赋上颜色,那么最后不就是一幅图片了么 ...

  8. JS开发HTML5游戏《神奇的六边形》(一)

    近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...

  9. java并发编程(三)线程挂起,恢复和终止的正确方法

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17095733    下面我们给出不用上述两个方法来实现线程挂起和恢复的策略--设置标志位. ...

  10. Oracle ITL(Interested Transaction List)理解

    ITL(Interested Transaction List) ITL是位于数据块头部的事物槽列表,它是由一系列的ITS(Interested Transaction Slot,事物槽)组成,其初始 ...