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 不采用。