简介:本文主要讲:函数的定义,外部参数的用处,无返回类型的三种函数定义方式闭包的定义,闭包的概念和用法,尾随闭包的写法,解除循环引用的方法
一、函数:
代码实现
- 函数的定义
- 格式
func 函数名(行参列表) -> 返回值 {代码实现} - 调用
let result = 函数名(值1, 参数2: 值2...)
func sum(a: Int, b: Int) -> Int {return a + b}let result = sum(10, b: 20)func demo(str: String) -> Void {print(str)}func demo1(str: String) -> () {print(str)}func demo2(str: String) {print(str)}demo("hello")demo1("hello world")demo2("olleh")- 外部参数
- 在形参名前再增加一个外部参数名,能够方便调用人员更好地理解函数的语义
- 格式:
func 函数名(外部参数名 形式参数名: 形式参数类型) -> 返回值类型 { // 代码实现 } - Swift 2.0 中,默认第一个参数名省略
func sum1(num1 a: Int, num2 b: Int) -> Int {return a + b}sum1(num1: 10, num2: 20)二、闭包:
与 OC 中的 Block 类似,
闭包主要用于异步操作执行完成后的代码回调,网络访问结果以参数的形式传递给调用方
闭包的定义
//: 定义一个 sum 函数func sum(num1 num1: Int, num2: Int) -> Int {return num1 + num2}sum(num1: 10, num2: 30)//: 在 Swift 中函数本身就可以当作参数被定义和传递let mySum = sumlet result = mySum(num1: 20, num2: 30)- 定义一个闭包
- 闭包 = { (行参) -> 返回值 in // 代码实现 }
in 用于区分函数定义和代码实现
//: 闭包 = { (行参) -> 返回值 in // 代码实现 }let sumFunc = { (num1 x: Int, num2 y: Int) -> Int inreturn x + y}sumFunc(num1: 10, num2: 20)- 最简单的闭包,如果没有参数/返回值,则
参数/返回值/in 统统都可以省略
let demoFunc = {print("hello")} 基本使用
GCD 异步
func loadData() {dispatch_async(dispatch_get_global_queue(0, 0), { () -> Void inprint("耗时操作 (NSThread .currentThread())")})}- 尾随闭包,如果闭包是最后一个参数,可以用以下写法
- 注意上下两段代码,
} 的位置
func loadData() {dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void inprint("耗时操作 (NSThread .currentThread())")}}func loadData() {dispatch_async(dispatch_get_global_queue(0, 0)) {print("耗时操作 (NSThread .currentThread())")}}自定义闭包参数,实现主线程回调
override func viewDidLoad() {super.viewDidLoad()loadData {print("完成回调")}}// MARK: - 自定义闭包参数func loadData(finished: ()->()) {dispatch_async(dispatch_get_global_queue(0, 0)) {print("耗时操作 (NSThread.currentThread())")dispatch_sync(dispatch_get_main_queue()) {print("主线程回调 (NSThread.currentThread())")// 执行回调finished()}}}override func viewDidLoad() {super.viewDidLoad()loadData4 { (html) -> () inprint(html)}}/// 加载数据/// 完成回调 - 传入回调闭包,接收异步执行的结果func loadData4(finished: (html: String) -> ()) {dispatch_async(dispatch_get_global_queue(0, 0)) {print("加载数据 (NSThread.currentThread())")dispatch_sync(dispatch_get_main_queue()) {print("完成回调 (NSThread.currentThread())")finished(html: "<h1>hello world</h1>")}}}循环引用
class NetworkTools: NSObject {/// 加载数据////// - parameter finished: 完成回调func loadData(finished: () -> ()) {print("开始加载数据...")// ...finished()}deinit {print("网络工具 88")}}class ViewController: UIViewController {var tools: NetworkTools?override func viewDidLoad() {super.viewDidLoad()tools = NetworkTools()tools?.loadData() {print("come here (self.view)")}}/// 与 OC 中的 dealloc 类似,注意此函数没有()deinit {print("控制器 88")}}运行不会形成循环引用,因为 loadData 执行完毕后,就会释放对 self 的引用
/// 完成回调属性var finishedCallBack: (()->())?/// 加载数据////// - parameter finished: 完成回调func loadData(finished: () -> ()) {self.finishedCallBack = finishedprint("开始加载数据...")// ...working()}func working() {finishedCallBack?()}deinit {print("网络工具 88")}运行测试,会出现循环引用
解除循环引用
/// 类似于 OC 的解除引用func demo() {weak var weakSelf = selftools?.loadData() {print("(weakSelf?.view)")}}loadData { [weak self] inprint("(self?.view)")}loadData { [unowned self] inprint("(self.view)")}闭包(Block) 的循环引用小结
- Swift
[weak self]self是可选项,如果self已经被释放,则为nil
[unowned self]self不是可选项,如果self已经被释放,则出现野指针访问
- Objc
__weak typeof(self) weakSelf;__unsafe_unretained typeof(self) weakSelf;
Ubuntu 15.10安装部署Swift开发环境 http://www.linuxidc.com/Linux/2016-01/126995.htm Swift 的变化:从 2.2 到 3.0 会带来什么 http://www.linuxidc.com/Linux/2015-12/126440.htm Swift 正式开源,同时开源 Swfit 核心库和包管理器 http://www.linuxidc.com/Linux/2015-12/125847.htm Apple Swift学习教程 http://www.linuxidc.com/Linux/2014-09/106420.htm 使用 Swift 构建一个 iOS 的邮件应用 http://www.linuxidc.com/Linux/2014-08/105542.htm Swift 2.0开源化 http://www.linuxidc.com/Linux/2015-06/118594.htm Linux下搭建Swift语言开发学习环境 http://www.linuxidc.com/Linux/2015-12/125983.htm
Swift 的详细介绍:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-04/129833.htm