没有自我的autorelase池访问方法中的Swift闭包 [英] Swift closures in autorelase pool accessing methods without self

查看:144
本文介绍了没有自我的autorelase池访问方法中的Swift闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是示例代码

func anyMethod() {
    // Nothing here       
}
var myVariable = ""

autoreleasepool { 
   anyMethod() // This should show error
   print(myVariable) // This should show error

}

它应该显示错误

在闭包中调用方法"anyMethod"需要显式的自我".使捕获语义明确化

Call to method 'anyMethod' in closure requires explicit 'self.' to make capture semantics explicit

但是我可以在没有自我的情况下呼叫anyMethod,我想知道为什么这没有显示错误

But I am able to call anyMethod without self, I wonder why this not showing error

为什么在没有self的情况下可以正常工作?

Why this is working without self ?

编辑

复制粘贴该类以重新生成

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


    }



}

推荐答案

在闭包中调用实例方法或引用实例属性需要显式的self,如果该闭包被传递给带有@escaping参数的函数.这明确表明self可能是在函数调用持续时间之外捕获的.

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.

如果功能参数不是@escaping,则不需要显式的self.

If the function parameter is not @escaping then no explicit self is required.

这是一个独立的示例:

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不使用.

In your example, Dispatch.main.async takes an escaping closure, but autorelease not.

这篇关于没有自我的autorelase池访问方法中的Swift闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆