gpt4 book ai didi

swift - 闭包中 "self"指的是什么 - Swift

转载 作者:行者123 更新时间:2023-11-28 09:56:26 28 4
gpt4 key购买 nike

我很难理解 Swift 中闭包中真正发生的事情,希望有人能帮助我理解。

class MyClass {

func printWhatever(words: String) {
print(words)
}

func doWhatever() {
dispatch_async(...) {
//why self
self.printWhatever("Hello")
}
}
}

self.printWhatever("Hello") 这行,为什么我必须使用 selfxCode 总是告诉我必须这样做,但我不确定为什么。所以,我的问题是闭包中到底存储了什么。我知道闭包捕获周围的上下文。但是多少钱? MyClass 的实例是否被捕获?

最佳答案

这是一个清晰的问题。任何时候您使用没有明确接收者的方法或属性名称时,它都会被隐式发送给 self。但是在匿名函数中,您必须明确说明这一事实。如果你说

printWhatever("Hello")

...您可能没有意识到您正在隐式捕获 self。所以你可能没有意识到,如果这个匿名函数是 itself to be storedself 的某个地方,您可能会遇到一个可怕的保留周期。因此,编译器强制您说self明确,以便您了解自己操作的含义。

证明是在某些情况下您不必必须在匿名函数中说self。考虑一下:

func printWhatever(words: String) {
print(words)
}

func doThis(f:()->()) {
f()
}

func doWhatever() {
doThis {
self.printWhatever("Hello") // self is required
}
}

在上面,你必须self,因为编译器不能保证不会发生保留循环。但是现在看看如果我们添加 @noescape 属性会发生什么:

func printWhatever(words: String) {
print(words)
}

func doThis(@noescape f:()->()) { // *
f()
}

func doWhatever() {
doThis {
printWhatever("Hello") // ok!
}
}

@noescape 属性保证传递的函数将立即执行而不存储。因此不再需要 self,因为不会发生保留循环。

就个人而言,我总是在允许的任何地方都说self,这是一种风格问题。我建议您也这样做。


注意:语言发生了变化 proposal那是rejected ,拒绝的理由之一就是我给出的理由:

The requirement to use self. within potentially-escaping closures is a useful indicator of the potential for retain cycles

关于swift - 闭包中 "self"指的是什么 - Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36237511/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com