This is sample code
func anyMethod() {
// Nothing here
}
var myVariable = ""
autoreleasepool {
anyMethod() // This should show error
print(myVariable) // This should show error
}
it should show error
Call to method 'anyMethod' in closure requires explicit 'self.' to make capture semantics explicit
But I am able to call anyMethod
without self, I wonder why this not showing error
Why this is working without self
?
EDIT
Copy paste this class to re-produce
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()
}
}
}
Calling an instance method or referencing an instance property in a closure requires explicit self
if that closure is passed to a function taking an @escaping
parameter. That makes it explicit that the self
is possibly captured beyond the duration of the function call.
If the function parameter is not @escaping
then no explicit self
is required.
Here is a self-contained example:
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
}
}
}
In your example, Dispatch.main.async
takes an escaping closure, but autorelease
not.