简体   繁体   English

Swift值在闭包内消失了

[英]Swift value disappeared inside a closure

I have the following code: 我有以下代码:

    let context = DBHelper.privateContext()
    context.performBlock({ [weak self] in
        if let ss = self {
            //1. 
            let articles = DBHelper.clientFetchArticles(context) 
            //2. 
            dispatch_async(dispatch_get_main_queue(), {
                //3. 
                ss.articles = articles
                ss.tableView.reloadData()
                ss.refreshControl.endRefreshing()
            })
        }
    })

After calling tableView.reloadData() , the following code runs: 调用tableView.reloadData() ,运行以下代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("ArticleCell", forIndexPath: indexPath) as! ArticleCell

    #4
    let article = articles[indexPath.row]


    cell.setupWithArticle(article)

    return cell
}

DBHelper.clientFetchArticles will return [Article] with 2 articles (of type ManagedObject). DBHelper.clientFetchArticles将返回[Article] 2篇文章( DBHelper.clientFetchArticles类型)。

  • At #1, when I print po articles[0].title , I get the correct title print out. 在#1,当我打印po articles[0].title ,我打印出正确的title

  • At #3, po articles.count prints 2 , po articles[0].title is also correct 在#3, po articles.count打印2po articles[0].title也是正确的

  • At #4, po self.articles[0].title gets nil. 在#4, po self.articles[0].title得到零。

I have tried dispatch_sync(dispatch_get_main_queue()) but still the same result. 我尝试过dispatch_sync(dispatch_get_main_queue())但结果仍然相同。

It is probably because your privateContext() implementation. 这可能是因为你的privateContext()实现。 After the execution of the callback, the captured context is deallocated, which invalidates your Article object fetched from that context. 执行回调后,将释放捕获的context ,这将使从该上下文获取的Article对象无效。

The recommended convention is to use the "main context" (the one passed all the way from your AppDelegate ) when dealing with UI fetch request. 建议的约定是在处理UI获取请求时使用“主要上下文”(从AppDelegate一直传递的那个)。 Use private context for the purpose of async updates (eg networing). 使用private context进行异步更新(例如,networing)。

My guess would be that the dispatch_async closure is capturing the values around it but because you aren't modifying the captured value, in this case articles , its making a copy of it instead of a reference to that array. 我的猜测是dispatch_async闭包是捕获它周围的值但是因为你没有修改捕获的值,在本例中是articles ,它会复制它而不是对该数组的引用。

The easy fix would be to make articles a property of that class 简单的解决方法是使articles成为该类的属性

Link to the Swift docs 链接到Swift文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM