2016-12-29 9 views
2

コアデータオブジェクトをバックグラウンドで読み込み、終了したらTableViewをリロードする必要があります。以下のコードは、空のtableViewいます:バックグラウンドでCore Dataオブジェクトを取得し、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クラスを使用するもう1つのソリューション。上記の例は次のようになります。

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

コアデータとTableView自身と対話する時はいつでもあなたはNSFetchedResultControllerを使用する必要があります。これは、自分でデータを取得するよりもはるかに安定して最適化されています。

私はあなたのコードについて非常に混乱しています。私はそのような解決策を見たことがありません。たぶん、あなたが閉鎖して、完了コールreloadDataに機能させるか、またはこのようなbeginUpdatesにブロック全体を置く必要があります。それはbackgroundTasksを実行するためのはるかに簡単であるため、

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

とにかく、私は強くNSFetchedResultsControllerを使用することをお勧めします。

関連する問題