我对目标c和iOS还是很陌生,非常感谢这里的帮助。
我一直在撞墙,试图使它正常工作,但仍然出现错误:
Failed to save to data store: The operation couldn’t be completed. (Cocoa error 1570.)
我正在做的是导入CSV文件。
据我所知,它部分起作用。正确地解析了CSV,获取了所有正确的值,并且已经调试通过,并且可以告诉KA对象都获取了正确的值。
但是我之间的关系方式似乎有问题-1570问题来自nil newTrainingDay的必填日期字段(似乎是在调试后填充的)。我有其他感觉不对劲的地方,但是不确定。
有人可以告诉我我在做什么错吗?
最佳答案
我认为问题出在创建新对象并将其插入数据库中,然后再搜索是否存在满足您需求的对象。以下面的代码为例:
// look for existing day
KATrainingDay *newTrainingDay = [NSEntityDescription insertNewObjectForEntityForName:@"KATrainingDay" inManagedObjectContext:self.managedObjectContext];
// Fetching
fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"KATrainingDay"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"date == %@", date]];
// Execute Fetch Request
fetchError = nil;
NSArray *trainingDays = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
// if you found it
if (!fetchError) {
if ([trainingDays count]) {
for (KATrainingDay *day in trainingDays) {
newTrainingDay = day;
}
} else {
// set name and date for training day
newTrainingDay.date = date;
newTrainingDay.name = trainingDayNameString;
[newTrainingDay addRoutinesObject:newTrainingRoutine];
[newTrainingRoutine addTrainingDaysObject:newTrainingDay];
}
首先,创建一个
KATrainingDay
并将其插入到上下文中,然后进行访存以查找具有正确日期的KATrainingDay
。如果找到它,则将指针(newTrainingDay
)分配给刚获取的对象。但是,您刚刚插入的对象仍然在上下文中(尽管您不再有指向它的指针),并且其所有属性和关系都将具有nil值。因此,当您保存时,该对象将无法通过所需的日期约束。要解决此问题,请仅在找不到与获取内容匹配的对象时才插入新对象:
// look for existing day
KATrainingDay *newTrainingDay;
// Fetching
fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"KATrainingDay"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"date == %@", date]];
// Execute Fetch Request
fetchError = nil;
NSArray *trainingDays = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
// if you found it
if (!fetchError) {
if ([trainingDays count]) {
for (KATrainingDay *day in trainingDays) {
newTrainingDay = day;
}
} else {
// set name and date for training day
newTrainingDay = [NSEntityDescription insertNewObjectForEntityForName:@"KATrainingDay" inManagedObjectContext:self.managedObjectContext]
newTrainingDay.date = date;
newTrainingDay.name = trainingDayNameString;
}
[newTrainingDay addRoutinesObject:newTrainingRoutine];
(其他实体也是如此)。在上面的代码中,我还将
addRoutinesObject:
调用移到了else块之外,因此无论您是找到现有的还是创建新的(我假设您想要的),它将执行。请注意,您不需要设置关系的两面-如果设置了一面,CoreData会自动为您做另一面(假设它们定义为逆)。另一个技巧是,您不需要for循环即可获取数组中的最后一项,只需使用:newTrainingDay = [trainingDays lastObject];