Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 在闭包中引用属性需要显式';赛尔夫';使捕获语义显式_Swift_Swift2 - Fatal编程技术网

Swift 在闭包中引用属性需要显式';赛尔夫';使捕获语义显式

Swift 在闭包中引用属性需要显式';赛尔夫';使捕获语义显式,swift,swift2,Swift,Swift2,尝试将HTML从web服务加载到webview时,出现以下错误: 闭包中对属性“webviewHTML”的引用需要显式的“self”。才能使捕获语义显式 这意味着什么,如何将HTML字符串加载到web视图中 func post(url: String, params: String) { let url = NSURL(string: url) let params = String(params); let request = NSMutableURLRequest(

尝试将HTML从web服务加载到webview时,出现以下错误:

闭包中对属性“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();
}

使用
self
是明确确认引用(也称为捕获)闭包中的构造(类/结构/枚举),这意味着在解除分配所述闭包之前不会解除分配
self


仔细想想,
self
可以很好地推断出来(实际上,在闭包之外使用
webviewHTML
时),但不推断它是一个有意的设计决策,因为Swift是一种安全第一语言

在回答这个问题之前,您必须知道内存周期是什么。看


现在您知道了什么是内存周期:

这个错误是我告诉你的

“嘿,NSURLSession闭包正试图保留webviewHTML 堆和self创建了一个内存周期,而我没有 我想克拉克先生想要这个,想象一下如果我们提出一个要求 永远,然后用户导航离开此页面。它不会 离开这个堆。我只是告诉你这些,但是你克拉克先生必须创建一个对自我的弱引用,并在结束语中使用它。”

我们使用
[弱自我]
创建弱引用。我强烈建议您查看附件中关于捕获含义的链接

有关更多信息,请参阅斯坦福大学课程

正确的代码

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


有关详细信息,请参见此

非常好的答案,谢谢您-现在这更有意义了。您通常做的是:将
数据、响应、错误更改为:
[弱自我]数据、响应、,在
中出错,然后在闭包中取消对
self
的引用,而不是取消对它的引用
self?
,因为
self
现在被设置为
nil
(又称为
nullable
),因此您必须取消对它的引用这里有一些微妙之处。斯坦福课程的视频使用[弱自我]来防止视图保留在堆上,作为不删除引用循环的一种精确方法。只有当闭包引用self并self保留对闭包的引用时,才会发生循环(这在Apple文档中有明确说明:“如果将闭包分配给类实例的属性,并且闭包的主体捕获该实例,也会发生强引用循环。”。此处的示例代码没有保留对闭包的引用,因此没有强引用cycle@Dale谢谢你的评论。这里的示例代码没有保留对闭包的引用,因此没有强引用循环。这是什么意思?实例本身没有对
post
函数的强引用吗?因此,对于
任务
?@Honey,变量task和request都是函数post()中的本地变量。一旦post退出,即使NSURLSession将继续异步执行,这些变量也将被释放。您可以在调用post()后在代码中设置断点来确认此行为在闭包中。在执行闭包之前,您应该看到post exit返回到调用方。也许,但这降低了抽象级别,降低了语言的规则性。此外,由于使用了引用计数,因此更安全。