swift2 对闭包中属性的引用需要显式的“self.”以使捕获语义显式化

9fkzdhlc  于 2022-11-06  发布在  Swift
关注(0)|答案(2)|浏览(204)

尝试将HTML从Web服务加载到Web视图中时,出现以下错误:
在闭包中引用属性“webviewHTML”需要显式“self.”以使捕获语义显式化
它的含义是什么?如何将HTML字符串加载到我的Web视图中?

func post(url: String, params: String) {

    let url = NSURL(string: url)
    let params = String(params);
    let request = NSMutableURLRequest(URL: url!);
    request.HTTPMethod = "POST"
    request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding)

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        if error != nil {
            print("error=\(error)")
            return
        }

        var responseString : NSString!;
        responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        webviewHTML.loadHTMLString(String(responseString), baseURL: nil)
    }
    task.resume();
}
nwlqm0z1

nwlqm0z11#

self的使用是引用(也称为捕获)闭包中的构造(类/结构/枚举)的显式确认,其含义是self将不会被释放,直到所述闭包被释放。
当你考虑它的时候,self可以很好地被推断出来,(当你在闭包之外使用webviewHTML的时候),但是不推断它是一个 * 有意 * 的设计决定,因为Swift是一个安全第一语言

cyvaqqii

cyvaqqii2#

在回答这个问题之前,你必须知道什么是内存循环。请参阅Apple文档中的解析类示例之间的强引用循环
现在你知道什么是记忆周期了:
这个错误是Swift编译器告诉你的
“嘿,NSURLSession closure 试图将webviewHTML保留在堆中,因此self==〉创建了一个内存循环,我认为Clark先生不希望在这里出现这种情况。想象一下,如果我们发出一个请求,这个请求持续了很长时间,然后用户离开了这个页面。它不会离开堆。我只是 * 告诉 * 你这个,然而你克拉克先生必须创造一个弱的自我参照,并在闭包中使用它。”
我们使用[weak self]创建(即captureweak 引用。我强烈建议您查看所附的关于捕获含义的链接。
有关更多信息,请参见斯坦福大学课程的this moment

正确的代码

func post(url: String, params: String) {

    let url = NSURL(string: url)
    let params = String(params);
    let request = NSMutableURLRequest(URL: url!);
    request.HTTPMethod = "POST"
    request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding)

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        [weak weakSelf self] data, response, error in

        if error != nil {
            print("error=\(error)")
            return
        }

        var responseString : NSString!;
        responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 

        weakSelf?.webviewHTML.loadHTMLString(String(responseString), baseURL: nil)
        // USED `weakSelf?` INSTEAD OF `self` 
    }
    task.resume();
}

有关详细信息,请参阅此Shall we always use [unowned self] inside closure in Swift

相关问题