2011-05-27 103 views
3

我正在實施iPhone應用程序的汽車管理器,並且無法保存新車。所以我有一個「Car」實體(和每個加載的DB),包含多個屬性。我有2個布爾值「保存」和「選擇」來跟蹤用戶添加到他的列表(如果添加,保存= 1)以及當前選擇哪輛車的車輛。因此,當我創建一輛新車時,我取消選擇舊車(選擇= 0),並且想要修改新車以設置其屬性saved = 1和selected = 1。iOS CoreData更新實體對象

這裏是我的功能:

- (IBAction)save 
{ 
    // Disable the previous car selection. 
    [self deselectCurrentSelectedCar]; 

    // Add new car as saved and selected. 
    [self saveAndSelectNewCar]; 

    // Call the delegate to dismiss the modal view. 
    [_delegate dismissAndSave]; 
} 

- (void)deselectCurrentSelectedCar 
{  
    // Fetched saved car. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]]; 
    [fetchRequest setEntity:entity]; 

    // Set predicate and sort orderings... 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"selected = 1"]; 
    [fetchRequest setPredicate:predicate]; 

    // Execute the fetch -- create a mutable copy of the result. 
    NSError *error = nil; 
    NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy]; 
    if (mutableFetchResults == nil) { 
     // Handle the error. 
     NSLog(@"[AddCarViewController] deselect car: car not found."); 
    } 
    else { 
     // Get car and assign new selected value. 
     Car *carToSave = (Car *)[mutableFetchResults objectAtIndex:0]; 
     [carToSave setSelected:[NSNumber numberWithInt:0]]; 

     // Save the car. 
     NSError *error = nil; 
     if (![self.managedObjectContext save:&error]) { 
      // Handle the error. 
      NSLog(@"[AddCarViewController] deselect car: error saving car."); 
     } 
     else { 
      NSLog(@"[AddCarViewController] deselect car: car saved."); 
     } 
    } 

    // Memory management. 
    [fetchRequest release]; 
    [mutableFetchResults release]; 
} 
- (void)saveAndSelectNewCar 
{ 
    // Get the car, and pass to the delegate the new settings. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]]; 
    [fetchRequest setEntity:entity]; 

    // Set predicate and sort orderings... 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(year=%@) AND (make=%@) AND (model=%@) AND (d=%@) AND (n=%@)", _car.year, _car.make, _car.model, _car.d, _car.n]; 
    [fetchRequest setPredicate:predicate]; 

    // Execute the fetch -- create a mutable copy of the result. 
    NSError *error = nil; 
    NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy]; 
    if (mutableFetchResults == nil) { 
     // Handle error. 
     NSLog(@"[AddCarViewController] save and select: can't save the new car"); 
    } 
    else { 
     // Get the car selected. 
     Car *selectedCar = (Car *)[mutableFetchResults objectAtIndex:0]; 
     [selectedCar setValue:[NSNumber numberWithInt:1] forKey:@"selected"]; 
     [selectedCar setValue:[NSNumber numberWithInt:1] forKey:@"saved"]; 

     // Save the car. 
     NSError *error = nil; 
     if (![self.managedObjectContext save:&error]) { 
      // Handle the error. 
      NSLog(@"[AddCarViewController] save and select: error saving car."); 
     } 
     else { 
      NSLog(@"[AddCarViewController] save and select: car saved."); 
     } 

     // Add car to delegate. 
     [EcoAppAppDelegate setUserCar:selectedCar]; 
    } 

    // Memory management. 
    [fetchRequest release]; 
    [mutableFetchResults release]; 
} 

而且我有這個記錄所有的時間:「保存錯誤車」在兩個功能上。所以肯定有一些錯誤。

此外,它是相當惱人的取車我想修改它,而不是立即做一個更新。如果有另一個請告訴我!

謝謝。

+0

什麼是錯誤?也許這會有所幫助? – 2011-05-27 21:05:52

+0

SQL執行期間出錯:約束失敗 – Dachmt 2011-05-27 21:09:40

+1

您需要提供更多信息。你有兩個NSLog語句可以打印「錯誤節能汽車」。你從哪一個錯誤中得到了錯誤?當發生這種情況時,NSError參數對此有何評論? Core Data可以告訴你哪裏出了問題,所以這是你應該關注的第一件事。 – 2011-05-27 21:12:00

回答

3

在你的頭文件中,你應該爲你的汽車設置一個可變數組。

NSMutableArray *carArray; 

@property (nonatomic, retain) NSMutableArray *carArray; 

然後確保合成它在你的實現文件。然後,當你從你的管理對象範圍內獲取,可以設置與內容的數組返回

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]]; 
[fetchRequest setEntity:entity]; 

// Execute the fetch -- create a mutable copy of the result. 
NSError *error = nil; 
NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy]; 
if (mutableFetchResults == nil) { 
    // Handle the error. 
    NSLog(@"[AddCarViewController] deselect car: car not found."); 
} else { 
    [self setCarArray:mutableFetchResults]; 
} 

這樣做將保留所有對象在管理對象方面,所以當你要修改的車,你可以在那裏找到它而不是再次獲取。如果您需要對其進行排序,則可以將使用您的某個屬性初始化的排序描述符作爲關鍵字應用。例如:

NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"selected" ascending:YES]; 
[carArray sortUsingDescriptors:[NSArray arrayWithObject:sorter]]; 

這將根據他們是否選擇與否的汽車進行排序。

至於爲什麼你得到一個錯誤,這可能是許多原因之一。通常情況下,如果您的某個屬性設置爲零,則MOC將無法保存,因此可能是原因。你可以從它得到一些細節,如果你設置如下的東西

if (![self.managedObjectContext save:&error]) { 
    NSLog(@"failed with error %@", error); 
} 

這將返回您遇到的實際錯誤。設置日誌以確保您指定了Car也是一個不錯的主意。像NSLog(@"selected car %@", carToSave);只是爲了安全

+0

我使用謂詞,因爲我預載了SQLite數據庫並在其中插入了超過10,000輛汽車。所以我不想去取一切。然後,我嘗試登錄汽車,我可以看到汽車,甚至已經做出改變等等。所以我猜想它只是一半工作,但是在設備上它崩潰了,而不是在模擬器上。我發現奇怪的是,我有一個屬性「epaClass」類型的字符串,它的值有時爲零,即使當我加載我的數據庫時,沒有任何屬性是NULL。 – Dachmt 2011-05-27 21:50:55

+0

這個屬性「epaClass」只是沒有意義,它應該始終是一個字符串,從來沒有一個NULL值,所以有什麼錯。也許試圖在更新我的對象時添加一個零值會產生這個錯誤。 – Dachmt 2011-05-27 22:02:41

+1

如果您正在加載很多汽車,我可以明確地使用謂詞。儘管將它們設置爲本地數組仍然可能是一個好主意(當然,在用謂詞獲取之後),然後從那裏修改它們。過去我遇到過問題,那些字符串設置爲零的應用程序在保存時崩潰了,所以這可能是問題,但唯一確定的方法是測試它。可能將它們設置爲默認值,至少存在一些內容。但是你說它可以在模擬器上工作,而不是在設備上? – justin 2011-05-27 22:07:53