2016-12-29 35 views
2

我想在后台加载核心数据对象,并且当完成it's,应该重新加载的TableView。下面的代码给出了一个空的tableView:在后台和tableView.reloadData撷取核心数据对象()

class ViewController: UIViewController { 
var fetchRequest: NSFetchRequest<Venue>! 
var venue:[Venue] = [] 
var coreDataStack: CoreDataStack! 

override func viewDidLoad() { 
     super.viewDidLoad() 
     fetchRequest = Venue.fetchRequest() 
     coreDataStack.storeContainer.performBackgroundTask {(context) in 
      do { 
       self.venue = try context.fetch(self.fetchRequesrt) 
      } catch { 
      } 
      DispatchQueue.main.async { 
       self.tableView.reloadData() 
      } 
     } 
} 

但是,如果我们在viewDidLoad中()没有大块写代码上面,一切工作正常和的tableView用数据填充:

venue = try! coreDataStack.managedContext.fetch(fetchRequesrt) 
tableView.reloadData() 

什么是错的上面的代码? 对于建议,我将不胜感激!

编辑。这是正确的解决方案:

class ViewController: UIViewController { 
var fetchRequest: NSFetchRequest<Venue>! 
var venue:[Venue] = [] 
var coreDataStack: CoreDataStack! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    fetchRequest = Venue.fetchRequest() 
    coreDataStack.storeContainer.performBackgroundTask {(context) in 
    do { 
    let venue = try context.fetch(self.fetchRequesrt) 
    venue.map {$0.objectID}.forEach{self.venue.append(self.coreDataStack.managedContext.object(with: $0) as! Venue)} 
    DispatchQueue.main.async { 
    self.tableView.reloadData() 
    } 
    } catch { 
    ... 
    } 
    } 
    } 
} 

另一个使用NSAsynchronousFetchRequest类的解决方案。上面的例子是这样的:

class ViewController: UIViewController { 
    var fetchRequesrt: NSFetchRequest<Venue>! 
    var venue:[Venue] = [] 
    var asyncFetchRequest: NSAsynchronousFetchRequest<Venue>! 
    var coreDataStack: CoreDataStack! 
    fetchRequest = Venue.fetchRequest() 
    override func viewDidLoad() { 
    super.viewDidLoad() 
    asyncFetchRequest = NSAsynchronousFetchRequest(fetchRequest:fetchRequest, completionBlock: { [unowned self] 
    (result: NSAsynchronousFetchResult) in 
    guard let venue = result.finalResult else { return } 
    self.venue = venue 
    self.tableView.reloadData() 
    }) 
    do { 
    try coreDataStack.managedContext.execute(asyncFetchRequest) 
    } catch { 
     ... 
    } 
    } 
    } 

回答

2

你应该使用NSFetchedResultController每当与核心数据和TableView本身交互。它比你自己获取数据要稳定和优化。

我对你的代码很迷茫,我从来没有见过这样的一个解决方案。也许你应该让函数关闭并在完成呼叫reloadData,或者把整个街区变成beginUpdates这样的:

self.tableView.beginUpdates() 
coreDataStack.storeContainer.performBackgroundTask {(context) in 
      do { 
       self.venue = try context.fetch(self.fetchRequesrt) 
      } catch {/*error goes here*/} 
     } 
self.tableView.endUpdates() 

无论如何,我强烈建议使用NSFetchedResultsController,因为它是进行backgroundTasks容易得多。