iosswiftnsautoreleasepool

Swift closures in autorelase pool accessing methods without self


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

enter image description here

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()
        }


    }



}

Solution

  • 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.