2015-11-05 51 views
0

我正試圖解決從CoreData提取數據比從Parse中檢索數據並將其保存到CoreData之前執行更早的問題。我如何實現一個隊列來執行從Parse提取數據?現在,當我啓動應用程序時,數據庫已更新,但tableView中未顯示。GCD和核心數據

CoreData檢索數據:

func fetchFromCoreData() { 

    do { 
     let results = try context.executeFetchRequest(fetchRequest) 

     medicines = results as! [Medicine] 
     print("FetchFromCoreData") 
     tableViewMedicines.reloadData() 

    } catch let error as NSError { 
     print("Could not fetch \(error), \(error.userInfo)") 
    } 

} 

讀取數據從parse:

func fetchFromParse() { 

    let entity = NSEntityDescription.entityForName("Medicine", inManagedObjectContext: context) 
    let query = PFQuery(className: PFUser.currentUser()!.username!) 
    query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in 
     if error == nil { 
      for object in objects! { 

       if let name = object["medicineName"] as? String, 
        amount = object["amountQuantity"] as? String, 
        time = object["time"] as? String 
       { 

        let predicate = NSPredicate(format: "name = %@", name) 
        self.fetchRequest.predicate = predicate 

        do{ 
         let fetchedEntities = try self.context.executeFetchRequest(self.fetchRequest) as! [Medicine] 
         //save to Core Data 


         if fetchedEntities.count <= 0 { 
          let medicine = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: self.context) 
          medicine.setValue(name, forKey: "name") 
          medicine.setValue(amount, forKey: "amount") 
          medicine.setValue(time, forKey: "time") 

         } 

        } catch let error as NSError{ 
         print(error) 
        } 
       } 
      } 

     } 

      do { 

       try self.context.save() 
       print("Context.save") 


      } catch let error as NSError { 
       print("Could not save \(error), \(error.userInfo)") 
      } 
      self.fetchFromCoreData() 



    } 


} 

我打電話給他們viewWillAppear

override func viewWillAppear(animated: Bool) { 
    if Reachability.isConnectedToNetwork() { 
     //fetching data from Parse 

     fetchFromParse() 
     fetchFromCoreData() 

     tableViewMedicines.reloadData() 

    } else { 

     //fetching data from Core data 
     fetchFromCoreData() 
     logOutButton.enabled = false 

    } 
} 
+0

我編輯了我的帖子。我在viewWillAppear中調用它們,但不知道它有什麼區別 – kiuzio2

+0

我不知道你會怎麼做,但是你可能不得不調用'fetchFromCoreData'方法中的'fetchFromParse'方法,這樣你就可以得到首先解析數據。您將測試網絡連接,然後從解析中獲取數據,否則您只會從磁盤獲取數據。 –

+0

這可能是因爲你的'findObjectsInBackground'回調將在未來的某個時刻被執行;在你重新加載你的表格數據之後。一個提示是重新考慮你調用tableViewMedicines.reloadData()的位置。 –

回答

0

這是發生,因爲findObjectsInBackgroundWithBlock使得網絡調用,並且只在以後執行它的塊n,異步,一旦網絡呼叫完成。你的代碼執行順序如下:

  1. 呼叫fetchFromParse()
  2. fetchFromParse(),調用解析。解析消失並在後臺與網絡通話...
  3. 致電fetchFromCoreData()
  4. 在稍後的某個時間點,Parse獲得網絡響應,並執行您的模塊。

你應該想到的是異步網絡調用將始終需要很長的時間,以及從網絡活動的回調將總是被推遲到將來的某個未知的時間。意思是,你不能以某種方式移動列表中前面第4步。

GCD不是這裏的答案。您必須等到網絡活動完成後再處理Parse的結果。與此同時,你的應用需要有響應,所以你不能坐在等待發生。

您需要做的是在Parse調用完成後重新執行Core Data提取。如果您仍然顯示早期抓取的結果,重新加載表視圖是不夠的。

+0

謝謝你解釋整個過程。所以你建議把'fetchFromParse'放在'fetchFromParse'中的'query'塊之後?我還有一個奇怪的問題,因爲當我把'tableView.reloadData()'放在'fetchFromParse'中時,它只會在'tableView'中顯示'CoreData'的一個調用。 – kiuzio2

+0

不,我建議在塊內調用'fetchFromCoreData()',而不是在它之後調用。總的來說,該塊將在稍後纔會執行,並且只有在發生後才需要重新執行抓取。另外請注意,您可能不在塊的主隊列中,因此您可能需要使用'dispatch_async'來讓Core Data和UI更新正常工作。 –