简体   繁体   中英

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:

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.

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