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:
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).
At #1, when I print po articles[0].title
, I get the correct title
print out.
At #3, po articles.count
prints 2
, po articles[0].title
is also correct
At #4, po self.articles[0].title
gets nil.
I have tried dispatch_sync(dispatch_get_main_queue())
but still the same result.
It is probably because your privateContext()
implementation. After the execution of the callback, the captured context
is deallocated, which invalidates your Article
object fetched from that context.
The recommended convention is to use the "main context" (the one passed all the way from your AppDelegate
) when dealing with UI fetch request. Use private context
for the purpose of async updates (eg 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.
The easy fix would be to make articles
a property of that class
Link to the Swift docs
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.