Swift值在闭包内消失了

时间:2016-01-08 02:43:42

标签: ios swift

我有以下代码:

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

调用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将返回[Article]两篇文章(ManagedObject类型)。

  • 在#1,当我打印po articles[0].title时,我得到了正确的title打印输出。

  • 在#3,po articles.count打印2po articles[0].title也正确

  • 在#4,po self.articles[0].title为零。

我尝试了dispatch_sync(dispatch_get_main_queue()),但结果仍然相同。

2 个答案:

答案 0 :(得分:2)

可能是因为您的privateContext()实施。执行回调后,捕获的context将被释放,这会使从该上下文中获取的Article对象无效。

建议的约定是在处理UI获取请求时使用“主要上下文”(从AppDelegate一直传递的那个)。使用private context进行异步更新(例如,网络连接)。

答案 1 :(得分:1)

我的猜测是dispatch_async闭包正在捕捉它周围的值但是因为你没有修改捕获的值,在这种情况下articles,它会复制它对该数组的引用。

简单的解决方法是使articles成为该类的属性

链接到Swift docs