我对Objective-C相对较新,并试图通过学习CoreData来努力,尽管有大量的Google搜索。我很好地掌握了mySQL和关系表,但我似乎无法理解如何让实体在CoreData中相互关联。
我喜欢在学习像CoreData这样的东西时为自己创建一些项目,所以我把它放在一起就是汽车服务跟踪器的简单概念(如换油,刹车等)。
我有2个代表车辆和油类变化的实体,如此......
和
......以及他们各自的关系。我不确定这是否需要一对一或一对多的关系,因为车辆会有很多换油,但也会有很多车......所以我猜这是我需要帮助理解的第一件事。
我正在使用SQLLite Manager来观察数据模型的变化。当我将Vehicle添加到我的Vehicle实体(基本上保存UITextFields)时,我可以看到对象在正确的实体中...
...当我将油更改添加到特定车辆时,我可以看到这些物体也被放入适当的实体......
..但是从下面可以看出,在尝试将特定换油与特定车辆相关联时似乎存在脱节......
现在,对于重要的问题......
1)。如何让个别换油仅与各自的车辆相关?现在无论选择哪种车辆,都会显示所有换油。我确信这与更新我提取的结果查询有关,但是从显示的表格中可以看出,我没有得到相应的换油次数。
2)。这可以通过理解问题1来解决......但如果我删除某个特定的车辆,那么我显然还需要删除与该车辆相关的任何换油。
我的保存方法如下。
- (IBAction)save:(id)sender {
Oil *oil = [NSEntityDescription insertNewObjectForEntityForName:@"Oil" inManagedObjectContext:self.managedObjectContext];
Vehicle *vehicle = [NSEntityDescription insertNewObjectForEntityForName:@"Vehicle" inManagedObjectContext:self.managedObjectContext];
// Which Vehicle
// newOil.vehicle = whichVehicle.text;
oil.vehicle = vehicle; // not working
// Format: Mileage
NSNumberFormatter *numberFormat = [[NSNumberFormatter alloc] init];
[numberFormat setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *myNumber = [numberFormat numberFromString:oilMileage.text];
oil.oilMileage = myNumber;
// Format: Date
NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
[dateFormat setDateFormat:@"MM-dd-yyyy"];
oil.oilDate = [dateFormat dateFromString:oilDate.text];
// Format: Notes
oil.oilNotes = oilNotes.text;
// save context
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate saveContext]; }
- >
- >
- >
- >
好的,我试图整合Dan Shelly建议的内容(这完全合情合理)但是我遇到了一些需要更多指导的障碍。
我的mainVC并没有使用tableView显示我的车辆(我将车辆总数限制为4,我用图标代表它们并将它们绑回CoreData中的vehicleID)。无论如何,因为它不是tableView我不能使用以下内容:
Vehicle *existingVehicle = (Vehicle *)[self.fetchedResultsController objectAtIndexPath:indexPath];
...因此,我在为获取的Vehicle对象创建实例时遇到问题,然后我可以将其传递给OilViewController。我有一个fetchRequest,它从CoreData返回正确的vehicleID,但我需要知道如何实际创建对象,以便我可以将它传递给OilViewController。我的fetchRequest看起来像这样......
- (void)fetchObjects {
NSLog(@"DVC-fetching Objects\n\n");
// Create Fetch Request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Vehicle" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
// Set Search Criteria
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"vehicleID == %@", vehicleID];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *array = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSLog(@"Object ID: %@", [array valueForKey:@"objectID"]);
NSManagedObjectID *moID = [array valueForKey:@"objectID"];
if (array != nil) {
NSUInteger count = [array count]; // May be 0 if the object has been deleted.
Vehicle *existingVehicle = (Vehicle *)[self.managedObjectContext existingObjectWithID:moID error:&error];
NSLog(@"Count: %lu", (unsigned long)count);
NSLog(@"Fetched Vehicle ID: %@",predicate);
NSLog(@"existingVehicle: %@", existingVehicle);
} else {
// Deal with error.
}
}
但我收到以下错误:
由于未捕获的异常终止应用' NSInvalidArgumentException',原因:' - [__ NSArrayI isTemporaryID]:无法识别的选择器发送到实例0x11d5b660'
如何为此返回的对象创建Vehicle实例,以便我可以将其传递给
答案 0 :(得分:1)
1)如何让个别换油只涉及各自的车辆?
您已经...只有您当前正在将换油与空Vehicle
物件相关联。这在车辆表中也可见(Z_PK = [3,4,5])。
当您需要添加新换油时,您可能已经可以访问此换油所需的相对Vehicle
对象。
此Vehicle
对象可能是您在车辆视图控制器中选择的对象。
因此,每次创建换油时,不要插入Vehicle
对象,只需将关系设置为现有车辆(您正在构建对象图,根据现有对象进行思考并将它们相互连接)。
2)删除:
从图片中可以看出,您应该设置删除规则,以实现目标。当您删除Vehicle
对象时,级联规则将删除相关的换油对象。当您删除换油对象时,相关的Vehicle
油关系将无效。
总结一下:
获取现有的Vehicle
对象:
//in your vehicle view controller :
Vehicle* existingVehicle = (Vehicle*)[self.fetchedResultsController objectAtIndexPath:indexPath];
将此对象传递给“换油视图控制器”。 添加新换油时,将车辆设置为现有对象:
Oil *oil = [NSEntityDescription insertNewObjectForEntityForName:@"Oil" inManagedObjectContext:self.managedObjectContext];
oil.vehicle = existingVehicle; // the one you passed along to this scope
//The rest of the oil content setting
//DON'T FORGET TO SAVE!
您可能希望将关系类型更改为多种类型的关系(Vehicle
可能有多次换油)。
这不会改变您的换油创建代码。
要查看特定Vehicle
对象的机油更改,您必须使用传递给机油更换视图控制器的现有车辆对象,并在FRC提取请求的谓词中使用它:
NSPredicate* p = [NSPredicate predicateWithFormat:@"vehicle = %@",existingVehicle];
fetchRequest.predicate = p;