美文网首页
Swift-闭包

Swift-闭包

作者: 捕梦少女的梦想 | 来源:发表于2018-09-04 16:47 被阅读0次

闭包是swift中非常重要的一个知识点。类似于objective-c中的block,其实函数就相当于一个特殊的闭包。闭包需要提前写好,在适当的时候再执行。

1、定义闭包

闭包的格式是(参数列表)->(返回值类型) in 实现代码

举一个最简单的例子。用常量记录一个代码块,按住option键就能看到,b1是一个闭包。再到适合的地方去调用它。


闭包1.png
let b1 = {
  print("干掉他们")
}
b1()

再来看一个带参数的闭包。在闭包中,参数、返回值和实现代码都是写在花括号里面的。in是用来定义分割和实现的。

let b2 = {
    (x:String)->() in print(x)
}

b2("string")

2、闭包案例

这个案例要模拟封装一个网络请求的类。利用闭包将jsonData类型的数据传递给展示页面。

  • 创建一个新的项目,选择swift语言


    闭包2.png
  • 封装一个网络请求的类HttpTool.swift继承自NSObject
  • 用异步线程模拟网络数据请求,再回到主线程中回调闭包
class HttpTool: NSObject {
    //闭包类型:(参数列表)->(返回值类型)
 
    func loadData(callback:@escaping(_ jsonData : String)->()) {
        DispatchQueue.global().async {
            print("发生网络请求:(Thread.current)")
        }
       
        DispatchQueue.main.async {
            ()->Void in
            print("获取到数据,并且回调:(Thread.current)")
           
            callback("jsonData数据")
        }
    }
}
  • 到需要接收数据的界面定义Httptool类的属性,设置一个初始化值,将初始值赋值给变量
  • 在swift中是不需要引入头文件的,文件之间可共享
import UIKit

class ViewController: UIViewController {

    var tools : HttpTool = HttpTool()
   
    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        //用闭包将json数据拿到
        tools.loadData { (jsonData) ->() in
            print("在viewcontroller中拿到数据(jsonData)" )
        }
    }
}
闭包3.png

3、尾随闭包

尾随闭包用于需要将一个很长的闭包表达式作为最后一个参数传递给函数。也就是说如果按时的最后一个参数是闭包,那么在调用它的时候就可以把这个闭包写在括号外面,并紧跟括号,函数的其他参数则仍然写在括号之中。

//这个函数接受一个String和一个闭包
//函数体内调用闭包,并且将String作为参数传递给闭包
func myFunc(strP:String,closeP:(String)->Void) {
    closeP(strP)
}

//普通调用
myFunc(strP: "hello", closeP: {(string) in print(string)})
//尾随闭包
myFunc(strP: "hello") {
    (string) in print(string)
}

4、逃逸闭包

当一个闭包作为参数传到一个函数中,但是该闭包要在函数返回之后才被执行,于是就称这样的闭包为逃逸闭包。也就是说闭包逃离了函数的作用域。写法是在这个闭包参数前加一个@escaping用来指明这个闭包是允许逃逸出该函数的。

  • 声明一个方法,这个方法是一个逃逸闭包

  • 该方法要做的事情,就是将闭包添加到数组中去

//定义数组,里面的元素都是闭包类型的
var callBackArray : [()->Void] = []

//定义一个接收闭包的函数
func testEscapingClosure(callBack:@escaping ()-> Void) {
    callBackArray.append(callBack)
}
  • 当改变数组的时候,取第0个元素调用。此时就改变了变量x的值
class SomeClass {
    var x = 10
    
    func doSomething(){
        testEscapingClosure {
            self.x = 100
        }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)
callBackArray.first?()
print(instance.x)

因为逃逸闭包是函数执行之后才会执行,所以可以这样理解:创建一个类的对象instance;在对象中初始化一个x=10;利用对象执行了函数doSomething;函数内部调用全局函数testEscapingClosure,期望修改instance对象的x值为100,但是此时并没有执行这个包含了赋值语句的闭包。

查找全局数组callBackArray,找到里面第一个元素,显然找到的是在testEscapingClosure函数中添加的闭包{self.x = 100},此时才通过全局数组的查询找出闭包并执行,于是x此时才被赋值为100。这就是在函数执行完毕后才执行闭包。刚好符合逃逸闭包的定义。

结论: 逃逸闭包将在函数执行之后执行,于是这段代码最后输出为100是因为闭包最后才被执行……

解决循环引用的三种方式

1、可以使用weak关键字将对象之间的联系变为弱引用

weak var weakself = self

2、第一种方式的简化

[weak self]

3、使用unowned解决

[unowned self]

但是该方法十分危险,要确保数据一定有值。否则会发生奔溃。

__weak 与__unretained有何区别?

__weak修饰的弱引用,如果指向的对象被销毁,那么指针会立马指向nil
__unretained修饰的弱引用,如果指向的对象被销毁,它的指针依然会指向之前的内存地址,很容易产生野指针(僵尸对象)

相关文章

  • Swift-闭包

    Swift-闭包 Swift闭包的含义 闭包是自包含的功能代码块,可以用作函数的参数或者返回值 闭包可以捕获上下文...

  • Swift-闭包

    闭包是swift中非常重要的一个知识点。类似于objective-c中的block,其实函数就相当于一个特殊的闭包...

  • swift-闭包

    闭包 ≈ block, 函数, 匿名函数 (闭包和函数都是引用类型,能改变值)(值类型不能改变值) 对上面的传的函...

  • Swift- 闭包

    闭包在Swift中非常有用。通俗的解释就是一个Int类型里存储着一个整数,一个String类型包含着一串字符,同样...

  • Swift-闭包

    Swift中的闭包和OC中的Block类似,语法格式不一样,但都是是用于c异步回调或者类之间的通信。本质上是一段可...

  • Swift-闭包

    闭包可以从定义它们的上下文中捕获和存储对任何常量和变量的引用。 这被称为关闭这些常量和变量。 Swift处理所有的...

  • Swift-闭包

    闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。 在Swift中的闭包与OC中的block类似。 ...

  • Swift-闭包

    闭包的特点:一个函数有权访问另外一个函数内的变量和参数 闭包—匿名函数 结尾闭包 衍生 内容捕获 闭包和函数是引用类型

  • Swift-闭包

    Swift 闭包 函数 ()->() Swift 中的闭包和 Objective-C 中的 block 类似,闭包...

  • swift-闭包

    这里总结主要看点 : 闭包传值问题 闭包和block基本一样,传值问题可以参照OC的中方式去考虑问题 . 引用学习...

网友评论

      本文标题:Swift-闭包

      本文链接:https://www.haomeiwen.com/subject/bdfnwftx.html