2017-07-18 62 views
0

在我的應用程序中,我使用的是核心數據,並且到目前爲止,一切都很好。我在嘗試更新條目時遇到問題。有趣的是,我可以更新除地址字段以外的實體中的所有內容。我沒有做任何不同的事情,但是當我嘗試僅更新那個帶有致命錯誤的字段時,應用程序崩潰:索引超出範圍。這是實際實體的屏幕截圖。iOS中的核心數據,索引超出範圍

enter image description here

這只是一些客戶信息和所有條目都是字符串。在我的編輯vc我已經使用var來保存客戶端信息,設置委託並使用一些謂詞。這裏是代碼:

//This is declared right under the class 
var myClientToEdit: NSManagedObject = NSManagedObject() 

//my save button action 
@IBAction func saveMyEdits(_ sender: Any) 
{ 
    //get the delegate 
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else 
    { 
     return 
    } 

    //get managedContext 
    let managedContext = appDelegate.persistentContainer.viewContext 

    //get the client's entry 
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Clients") 

    fetchRequest.returnsObjectsAsFaults = false 

    //use predicates to make sure it is the client I need 
    fetchRequest.predicate = NSPredicate(format: "lastName == %@", mylastName) 
    fetchRequest.predicate = NSPredicate(format: "firstName == %@", myfirstName) 
    fetchRequest.predicate = NSPredicate(format: "address = %@", myaddress) 

    do { 
     var myClientToEdit = try managedContext.fetch(fetchRequest) 
     let myObject = myClientToEdit[0] 

     //my correct client is printed 
     print(myObject) 

     //using new entries to set new values 
     myObject.setValue(lastName.text!, forKey: "lastName") 
     myObject.setValue(firstName.text!, forKey: "firstName") 
     myObject.setValue(address.text!, forKey: "address") 
     myObject.setValue(city.text!, forKey: "city") 
     myObject.setValue(state.text!, forKey: "state") 
     myObject.setValue(zip.text!, forKey: "zipCode") 
     myObject.setValue(phoneDay.text!, forKey: "phoneDay") 
     myObject.setValue(phoneEve.text!, forKey: "phoneEvening") 
     myObject.setValue(email.text!, forKey: "email") 

     do{ 
      //save 
      try managedContext.save() 
     }catch let error as NSError{ 
      print(error) 
     } 

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

    //dismis upon saving edits 
    self.dismiss(animated: true, completion: nil) 
} 

當我回到我的詳細客戶端vc我做同樣的事情,但只是從核心數據讀取。這裏是詳細的客戶端vc的代碼。

override func viewWillAppear(_ animated: Bool) 
{ 
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else 
    { 
     return 
    } 

    let managedContext = appDelegate.persistentContainer.viewContext 

    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Clients") 

    fetchRequest.predicate = NSPredicate(format: "lastName == %@", myLastName) 
    fetchRequest.predicate = NSPredicate(format: "firstName == %@", myFirstName) 
    fetchRequest.predicate = NSPredicate(format: "address == %@", myAddress) 

    do { 
     var thisIsTheClient = try managedContext.fetch(fetchRequest) 
     let myObject = thisIsTheClient[0] 

     print(myObject) 

     lastNameLabel.text = myObject.value(forKey: "lastName") as? String 
     firstNameLabel.text = myObject.value(forKey: "firstName") as? String 
     myCityLabel.text = myObject.value(forKey: "city") as? String 
     myAddressLabel.text = myObject.value(forKey: "address") as? String 
     myStateLabel.text = myObject.value(forKey: "state") as? String 
     myZipLabel.text = myObject.value(forKey: "zipCode") as? String 
     myDayLabel.text = myObject.value(forKey: "phoneDay") as? String 
     myEveLabel.text = myObject.value(forKey: "phoneEvening") as? String 
     myEmailLabel.text = myObject.value(forKey: "email") as? String 

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

錯誤在線:let myObject = thisIsTheClient [0]。但只有當我嘗試編輯地址。 thisIsTheClient也在類中定義。我知道索引超出範圍與嘗試將某些東西放在數組中沒有的東西有關,但我不明白爲什麼只有當我嘗試編輯地址時纔會這樣做。所有其他條目都完美更新。

編輯17年7月19日

感謝大家的答覆! Maor和Jay的謂詞都是正確的。我只搜索客戶端的地址,而不是前三個屬性。在傑伊關於這個變種的記錄之後,我能夠將新數據傳回並且上傳var並搜索新記錄。再次感謝!

+1

您是否嘗試過調試SQL操作?看起來像你的SQL地址操作給出了一些錯誤。調試SQL操作編輯您的Scheme並在參數部分添加以下代碼 -com.apple.CoreData.Logging.stderr 1 –

+0

當您已經存儲了一些數據時,您是否添加了地址屬性? – Roy

+0

@羅伊,是的,地址,以及所有其他屬性都有值。我正在修改它們編輯vc – Douglas

回答

1

我認爲你有一個不同的問題比你認爲它是什麼。 首先,當你寫:

fetchRequest.predicate = NSPredicate(format: "lastName == %@", myLastName) 
fetchRequest.predicate = NSPredicate(format: "firstName == %@", myFirstName) 
fetchRequest.predicate = NSPredicate(format: "address == %@", myAddress) 

只有最後一行是考慮到,因爲它是重寫之前無論發生什麼事,這意味着在你的情況下,它只會查找地址屬性(我想這爲什麼你認爲你的問題只在地址欄中。) 你應該遵循@Jay提供給你做的複合謂詞。

第二件事(如果我理解正確的話)是,您將地址更改爲myAddressLabel.text保存的任何文本並保存。但是,當從核心數據讀取詳細信息vc時,仍嘗試通過「myAdress」變量進行查詢,該變量與您保存的變量不同。如果是這種情況,它解釋了爲什麼你會得到這個錯誤信息 - 它只是沒有找到任何與你的搜索相匹配的東西,所以當你嘗試從一個空數組中獲得第一個元素時,它告訴你它已經失效邊界...

+0

謝謝!我根據你和Jay的建議修正了謂詞。我甚至不知道我有這個不正確的!而關於變量的提示幫助我發現我正在使用一些不正確的數據執行取回操作。從我+1。仍然得到錯誤,但那是因爲我正在查找一條記錄,這個記錄不再存在。我只需要找到一種方法來更新正確的值。 – Douglas

1

我,而不是僅僅試圖改變讀取請求的財產,以你必須使用一個複合謂語謂詞結合起來相當肯定,:

let predicate1:NSPredicate = NSPredicate("label = 'foo'") 
let predicate2:NSPredicate = NSPredicate("label = 'bar'") 
let compound:NSCompoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2]) 
+0

謝謝,我會研究這一點。 – Douglas

+0

那麼,工作!我甚至沒有注意到搜索和謂詞的這個方面。從我+1。儘管雙重平等似乎與單一平等沒有什麼不同?謝謝。 – Douglas

+1

兩者都等於標誌工作。 – sschale