2011-05-27 44 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