Swift语义使用?调用(可空)弱引用上的方法。操作者

问题描述 投票:6回答:2

回到使用ARC的Objective-C,这是不安全的:

MyClass* someObject = ...
__weak MyClass* weakSomeObject = someObject;
doSomething(^{
    [weakSomeObject someMethod];
});

为什么?因为简单地调用方法不会导致ARC保留对象,因此someObject实例可能会在执行someMethod的过程中被释放和释放

将此转化为快速,它转换如下:

let someObject: MyClass = ...
doSomething { [weak someObject]
    someObject?.someMethod()
}

My question is, what are the semantics of the ?. operator in swift regarding ARC, and is it safe to use with weak reference method calls?

我可以想象swift编译器将上面的代码翻译成这样的代码:

let someObject: MyClass = ...
doSomething { [weak someObject]
    if let tmp = someObject { 
        tmp.someMethod()
    }
}

如果它这样做,那么它确实是安全的,因为tmp是一个强大的参考,因此会导致ARC在调用someMethod的整个过程中保留对象

但是,我还可以想象,由于性能原因或其他原因,它会转换成没有ARC保留的东西。

有谁知道它实际上做了什么,是否有一个规范或文件使这个明确?

swift weak-references
2个回答
0
投票

要获得第一个要点:

  • 闭包捕获上下文。
  • 如果let,guard etc仅检查optional是否包含实际值但是不捕获它的上下文。

现在关于?。它是可选的链接,如果调用哪个方法的对象是nil,它将不会调用方法以及完整链失败(如果您使用另一个方法调用跟踪返回值,否则)。

关于weakunowned引用封闭内的已使用对象:

  • weak没有创建对象的强引用,所以它使它成为可选的,因为当它被调用时对象可能不存在
  • unowned以及weak不会创建强引用,但是对象不是可选的,因此您必须保证闭包不会比它使用的对象寿命更长,因为您将获得崩溃引用不存在的对象。

希望能帮助到你。


0
投票

简短的回答是肯定的,这是安全的。更长的解释和链接如下:

为Swift中的类型定义的方法是curried函数,如下所示:

class MyClass {
  func doSomething() {
      // I can access self in here
  }
}

print(type(of: MyClass.doSomething)) //(MyClass) -> () -> ()

换句话说,在类型上定义的函数是curry,因此必须首先传递对self的引用,()->()在返回的部分应用函数中强烈捕获(self

当你在MyClass的实例上调用方法时(不是类型本身),它会自动执行传入MyClass.doSomething实例的初始部分应用程序,然后由实际调用的结果闭包强烈捕获。

所以(MyClass) -> () -> ()的类型是MyClass().doSomething,而() -> ()的类型是() -> (),其中最初的MyClass参考已经被捕获在weak var test: MyClass? = MyClass() test?.doSomething() 内。

鉴于以下代码:

test

在第2行,发生了一些事情。首先,如果(MyClass) -> () ->()是非零的,它将被传递给MyClass类型的方法实现,并由MyClass类型的curried函数()->()捕获。此捕获的引用是可以在该实例方法中使用的“self”。

然后,调用self类型的结果部分应用函数,并且一旦函数执行,就释放来自上面的https://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/的强引用/捕获。

因此,答案是肯定的,在弱引用上调用实例方法是安全的,因为实例方法实际上强大地捕获实例,直到它执行为止。

这篇文章讨论了如何更详细地描述Swift中的实例方法,以及指向信息的初始dev论坛源的链接。

http://rosslebeau.com/2016/sneaky-reference-cycles-swift-instance-methods


更新:

关于这种机制的一些其他有趣和深入的文章:

https://www.klundberg.com/blog/capturing-objects-weakly-in-instance-method-references-in-swift/

qazxswpoi

© www.soinside.com 2019 - 2024. All rights reserved.