美文网首页Swift
Swift中的闭包

Swift中的闭包

作者: 某人会写代码 | 来源:发表于2017-02-16 14:01 被阅读18次

在Swift中有两种闭包,逃逸闭包(@escaping)和非逃逸闭包(@nonescaping)。从Swift 3开始,函数中传递的闭包默认为@nonescaping。

怎么让一个闭包逃逸?

简而言之,逃逸闭包就是函数运行完后,闭包还没有执行,这时称闭包逃逸了。

var bar_closure : ()->Void = {}
func bar(closure: @escaping ()->Void) {
    bar_closure = closure
}

另一个稍微复杂一点的例子, 来自http://stackoverflow.com/questions/39504180/escaping-closures-in-swift

class A {
    var closure: (() -> Void)?
    func someMethod(closure: () -> Void) {
        self.closure = closure
    }
}

class B {
    var number = 0
    var a: A = A()
    func anotherMethod() {
        a.someMethod { self.number = 10 }
    }
}

结论:

可见让一个闭包逃逸最简单的方法就是在函数外定义一个变量来保存该闭包。

小心“强引用循环” (retain cycles)!

观察上面的例子,可能发现它其实存在内存泄漏,因为有强引用循环。给两个类添加deinit, 发现A,B实例均没有被释放。

class A {
    var closure: (() -> Void)?
    func someMethod(@escaping closure: () -> Void) {
        self.closure = closure
    }
   deinit {
        print("A deinit")
    }
}

class B {
    var number = 0
    var a: A = A()
    func anotherMethod() {
        a.someMethod { self.number = 10 }
    }
   deinit {
        print("B deinit")
    }
}

let b = B()
b.anotherMethod()

引用循环图

swift_closure_ref_cycle.png

解决方法

closure 中使用弱引用捕获self的时候,

func anotherMethod() {
        a.someMethod { [weak self] in
            self?.number = 10
        }
 }
swift_closure_weak_ref.png

这样当B被释放的时候,其子层级A,A.closure均会被释放。

如果A.someMethod是@nonescaping闭包,会有引用循环么?

func someMethod(closure: () -> Void) {
        closure()
}

答案是不会的,因为此时的引用关系如下图, A.someMethod运行结束后,closure即被释放。

closure_B_A_ref.png

参考文章:

https://krakendev.io/blog/weak-and-unowned-references-in-swift

相关文章

  • Swift-闭包

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

  • Swift闭包和函数

    函数在Swift中只是一种特殊的闭包,闭包在Swift语言中是一等公民,支持闭包嵌套和闭包传递。Swift中的闭包...

  • swift4 闭包

    swift 闭包 闭包:swift 中 函数是闭包的一种类似于oc的闭包闭包表达式(匿名函数) -- 能够捕获上下...

  • Swift学习笔记(1)

    SWift学习笔记 闭包 闭包表达式 闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 ...

  • swift中的闭包

    swift中的闭包 闭包是自包含的函数代码块,可以在代码中被传递和使用。swift中的闭包与C和Objective...

  • Swift总结

    1.闭包 swift中的闭包类似于oc中的block回调,但是swift的闭包有很多种写法,具有多变性,今天就来总...

  • swift 闭包(闭包表达式、尾随闭包、逃逸闭包、自动闭包)

    闭包是自含的函数代码块,可以在代码中被传递和使用 闭包和swift的对比 Swift 中闭包与OC的 block ...

  • 闭包

    闭包 本节内容包括: 闭包表达式 尾随闭包 值捕获 闭包是引用类型 Swift 中的闭包与 C 和 Objecti...

  • Swift入门基础5——闭包

    何为闭包? Swift中的闭包和OC中的block很相似(其实也有其他语言有闭包的概念)。所谓闭包,就是可以捕获其...

  • swift学习笔记 ⑥ —— 闭包

    Swift学习笔记 - 文集 闭包,就是能够读取其他函数内部变量的函数。Swift 中的闭包与 C 和 OC 中的...

网友评论

    本文标题:Swift中的闭包

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