[英]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
打印2
, po 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.