自我是否被包含在嵌套函数中?

32

使用闭包时,我通常会在捕获列表中添加[weak self],然后对self进行空值检查:

使用闭包时,我通常会在捕获列表中添加[weak self],然后对self进行空值检查:

func myInstanceMethod()
{
    let myClosure =
    {
       [weak self] (result : Bool) in
       if let this = self
       { 
           this.anotherInstanceMethod()
       }
    }   

    functionExpectingClosure(myClosure)
}

如果我使用嵌套函数代替闭包(或者说使用嵌套函数是否是个好习惯),那么如何在self上执行空值检查(或者说这种检查是否必要)?

func myInstanceMethod()
{
    func nestedFunction(result : Bool)
    {
        anotherInstanceMethod()
    }

    functionExpectingClosure(nestedFunction)
}

从rintaro的答案中学到了一些东西,我在这里写了一个更加健壮的答案这里 - mfaani
2个回答

38

很不幸,只有闭包拥有像 [weak self] 这样的“捕获列表”功能。对于嵌套函数,您必须使用普通的 weakunowned 变量。


func myInstanceMethod() {
    weak var _self = self
    func nestedFunction(result : Bool) {
        _self?.anotherInstanceMethod()
    }

    functionExpectingClosure(nestedFunction)
}

4
这是否在官方文档中呢? - Ian Bytchek
1
看起来这是真的。我进行了测试,发现闭包中的弱引用并没有传递到嵌套函数中的self。所以所谓的“干净代码”也就这样了。 - possen
1
似乎不再是这种情况了。 - MLefrancois

-4

看起来不再是这种情况了。在Swift 4.1中,这是有效的:

class Foo {
    var increment = 0
    func bar() {
        func method1() {
            DispatchQueue.main.async(execute: {
                method2()
            })
        }

        func method2() {
            otherMethod()
            increment += 1
        }
        method1()
    }

    func otherMethod() {

    }
}

问题仍然存在:如何捕获self

如果您所说的“有效”是指self没有被强引用,那么我不能同意。在我的情况下,我有一个闭包,并且我从这个闭包中调用了一个嵌套的func,但是类不会被释放,即deinit没有被调用。至少这就是我的研究/调试所显示的。 - mathz
这里将会强烈捕获它。 - adamz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接