Swift 没有 self 的自动释放池访问方法中的闭包
Swift closures in autorelase pool accessing methods without self
这是示例代码
func anyMethod() {
// Nothing here
}
var myVariable = ""
autoreleasepool {
anyMethod() // This should show error
print(myVariable) // This should show error
}
它应该显示错误
Call to method 'anyMethod' in closure requires explicit 'self.' to make capture semantics explicit
但是我可以在没有自己的情况下调用anyMethod
,我想知道为什么这没有显示错误
为什么这在没有 self
的情况下也能正常工作?
编辑
复制粘贴这个class重新制作
import Foundation
import UIKit
class AppGlobalManager:NSObject {
var currentUserID:String?
//Please ignore the method content as it is not the question
func appendLog(string:String?) {
print("LOG:",string)
}
func autoRelaseTest() {
autoreleasepool {
appendLog(string: "Any Log") // NO ERROR
}
}
func normalFunctionTest () {
normalFuncWithClosure {
appendLog(string: "Test") //Call to method 'appendLog' in closure requires explicit 'self.' to make capture semantics explicit
}
}
func normalFuncWithClosure (completion:@escaping() -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
completion()
}
}
}
如果将闭包传递给采用 @escaping
参数的函数,则在闭包中调用实例方法或引用实例 属性 需要显式 self
。这明确表示 self
可能在函数调用持续时间之外被捕获。
如果函数参数不是 @escaping
则不需要显式 self
。
这是一个 self-contained 示例:
func funcTakingNonescapingClosure(_ closure: () -> Void) { }
func funcTakingEscapingClosure(_ closure: @escaping () -> Void) { }
class Foo {
func anyMethod() { }
var myVariable = ""
func test() {
funcTakingNonescapingClosure {
anyMethod() // No error
print(myVariable) // No error
}
funcTakingEscapingClosure {
anyMethod()
// Call to method 'anyMethod' in closure requires explicit 'self.'
// to make capture semantics explicit
print(myVariable)
// Reference to property 'myVariable' in closure requires explicit
// 'self.' to make capture semantics explicit
}
}
}
在您的示例中,Dispatch.main.async
采用转义闭包,但 autorelease
不采用。
这是示例代码
func anyMethod() {
// Nothing here
}
var myVariable = ""
autoreleasepool {
anyMethod() // This should show error
print(myVariable) // This should show error
}
它应该显示错误
Call to method 'anyMethod' in closure requires explicit 'self.' to make capture semantics explicit
但是我可以在没有自己的情况下调用anyMethod
,我想知道为什么这没有显示错误
为什么这在没有 self
的情况下也能正常工作?
编辑
复制粘贴这个class重新制作
import Foundation
import UIKit
class AppGlobalManager:NSObject {
var currentUserID:String?
//Please ignore the method content as it is not the question
func appendLog(string:String?) {
print("LOG:",string)
}
func autoRelaseTest() {
autoreleasepool {
appendLog(string: "Any Log") // NO ERROR
}
}
func normalFunctionTest () {
normalFuncWithClosure {
appendLog(string: "Test") //Call to method 'appendLog' in closure requires explicit 'self.' to make capture semantics explicit
}
}
func normalFuncWithClosure (completion:@escaping() -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
completion()
}
}
}
如果将闭包传递给采用 @escaping
参数的函数,则在闭包中调用实例方法或引用实例 属性 需要显式 self
。这明确表示 self
可能在函数调用持续时间之外被捕获。
如果函数参数不是 @escaping
则不需要显式 self
。
这是一个 self-contained 示例:
func funcTakingNonescapingClosure(_ closure: () -> Void) { }
func funcTakingEscapingClosure(_ closure: @escaping () -> Void) { }
class Foo {
func anyMethod() { }
var myVariable = ""
func test() {
funcTakingNonescapingClosure {
anyMethod() // No error
print(myVariable) // No error
}
funcTakingEscapingClosure {
anyMethod()
// Call to method 'anyMethod' in closure requires explicit 'self.'
// to make capture semantics explicit
print(myVariable)
// Reference to property 'myVariable' in closure requires explicit
// 'self.' to make capture semantics explicit
}
}
}
在您的示例中,Dispatch.main.async
采用转义闭包,但 autorelease
不采用。