2017-02-23 78 views
1

我想要將從遠程文件下載的一些數據存儲在CoreData中。他的數據可能以前已經下載過,然後需要將更改添加到核心數據。 我使用這裏顯示的代碼。在三個地方我使用Fetchrequest來檢查數據是否已經存在於數據庫中。我對請求使用謂詞。在代碼中,我添加了評論來區分它們。如果該項目已經在coreData中,我更新數據,否則我會實例化一個新項目。將該項目添加到核心數據的代碼位於該類的便利init中。這工作正常。我得到的問題是這樣的: 這個代碼中的第一次id等於0,所以schoolFetch被執行。添加謂詞nr 1不會導致錯誤,並且學校類的實例化將其id設置爲0. 第二次id = 1。這意味着位置是學校的一部分的locationItem被檢查並實例化。爲了將位置添加到學校,執行fetchrequest以獲得schoolInstance。使用謂詞2。儘管之前添加的schoolInstance沒有被檢索,但這不會產生錯誤,但是如果謂詞沒有被使用(註釋掉)。 檢索schoolInstance之後,我使用fetchrequest來檢查位置是否已經在coredata中。如果沒有,它被實例化,否則其數據被更新。謂詞nr 3給出了一個運行時錯誤,除了EXC_BAD_ACCESS(代碼= 1,地址= 0x1)外其他都沒有說明。在調試器窗口中沒有給出錯誤描述。 所以我有兩個問題: a)謂詞nr 2爲什麼不返回先前插入的項目? b)爲什麼謂詞nr 3給出錯誤?瞭解快速添加謂詞到NSFetchrequest

我以這種方式組織這段代碼,因爲它有可能首先接收有關學校信息的位置信息。

if id == 0 { 
     //get school 
     let schoolFetch = NSFetchRequest<StreekgidsSchool>(entityName: "School") 
     schoolFetch.predicate = NSPredicate(format: "locationId == %@", id) // predicate 1 

     do { 
      let fetchedSchool = try streekgidsModel?.context.fetch(schoolFetch) 
      if let school = fetchedSchool?.first{ 
       school.name = name 
       school.locationId = id 
       school.colorValue = color 
       schoolInstance = school 
      } 
      else { 
       //create new entry in coredata for school 
       schoolInstance = StreekgidsSchool(name: name, context: (streekgidsModel?.context)!) 
       schoolInstance?.locationId = id 
       schoolInstance?.colorValue = color 
      } 
     } catch { 
      fatalError("Failed to fetch Schooldata: \(error)") 
     } 
    } 
    else { 
     //check if school already is defined 
     let schoolFetch = NSFetchRequest<StreekgidsSchool>(entityName: "School") 
     schoolFetch.predicate = NSPredicate(format: "locationId == %@", 0) //predicate 2 

     do { 
      let fetchedSchool = try streekgidsModel?.context.fetch(schoolFetch) 
      if let school = fetchedSchool?.first{ 
       schoolInstance = school 
      } 
      else { 
       //create new entry in coredata for school 
       schoolInstance = StreekgidsSchool(id: 0, context: (streekgidsModel?.context)!) 
      } 
     } catch { 
      fatalError("Failed to fetch Schooldata: \(error)") 
     } 
     //get location 
     let locationFetch = NSFetchRequest<StreekgidsLocation>(entityName: "Location") 
     locationFetch.predicate = NSPredicate(format: "locationId == %@", id) //predicate 3 

     do { 
      let fetchedLocation = try streekgidsModel?.context.fetch(locationFetch) 
      if let location = fetchedLocation?.first{ 
       location.name = name 
       location.locationId = id 
       location.colorValue = color 
       location.school = schoolInstance 
      } 
      else { 
       //create new entry in coredata for location 
       let locationInstance = StreekgidsLocation(name: name, context: (streekgidsModel?.context)!) 
       locationInstance.locationId = id 
       locationInstance.colorValue = color 
      } 
     } catch { 
      fatalError("Failed to fetch Schooldata: \(error)") 
     } 

    } 
+0

是不是%@通常用於表示謂詞中的對象或字符串?現在不能輕易檢查,但我會檢查什麼會更好地匹配你的id作爲一個Int。可能%i或%d – Magnas

+0

該文檔指出以下內容:「%@是一個對象值的var arg替換 - 通常是字符串,數字或日期」。此外,所有三個謂詞的格式都是相同的,但只有第三個謂詞會導致錯誤 – KvdLingen

+0

或者可能:let predicate = NSPredicate(format:「id ==%@」,id as NSNumber) – Magnas

回答

1

沒錯。 %@期待Foundation對象作爲參數,但Int不是對象。所以你的id(設置爲零)被解釋爲零。這也是爲什麼你的謂詞2沒有任何返回值,以及爲什麼當你註釋它時檢索結果的原因。只有第三個謂詞會引發運行時錯誤,但事實上,所有三個謂詞都不正確,前兩個謂詞不會立即以可見方式落下。你有沒有嘗試用%@代替%d。

而你指出%u爲無符號整數。