对 CoreData 执行添加/更新时出现问题
Posted
技术标签:
【中文标题】对 CoreData 执行添加/更新时出现问题【英文标题】:Issue with performing add/update to CoreData 【发布时间】:2013-07-05 20:10:10 【问题描述】:我有一个NSArray
持有几个NSDictionary
,每次我保存一个NSDictionary
对象并将其添加到NSArray
时,我都会将它发送到添加/更新函数。
我知道我读取的数据是正确的,当我使用没有更新功能的情况下添加数据时,所有数据都插入到CoreData
,但我想添加更新功能来验证我放入的数据。
现在,该函数添加第一个对象,然后一遍又一遍地转到“更新”。
怎么了?
我的代码:
-(void)updateOrAddTrap:(NSMutableDictionary*)trapObject
NSInteger trapID = [trapObject[@"id"] integerValue];
Trap *trapEntity = nil;
NSError *error = nil;
Boolean success = true;
self.fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Trap"];
self.predicate = [NSPredicate predicateWithFormat:@"trapID == %d", trapID];
[self.fetchRequest setPredicate:self.predicate];
NSArray *results = [self.managedObjectContext executeFetchRequest:self.fetchRequest error:&error];
if (results == nil)
// Handle error
NSLog(@"HANDLE ERROR");
success = false;
else if ([results count] == 0)
// Nothing to update, add new trap
NSLog(@"NOTHING TO UPDATE | ADD NEW");
// Create a new record (row)
trapEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Trap" inManagedObjectContext:self.managedObjectContext];
else
NSLog(@"UPDATE EXISTING OBJECT");
trapEntity = results[0]; // There should be only one object for the ID.
if (trapEntity != nil)
// Set properties for new or existing object ...
// Int
int alarmDistance = [[trapObject objectForKey:ALARMDISTANCE] intValue];
int type = [[trapObject objectForKey:TYPE] intValue];
int roadNumber = [[trapObject objectForKey:ROADNUMBER] intValue];
int trap_id = [[trapObject objectForKey:ID] intValue];
int polys = [[trapObject objectForKey:POLYGONS] intValue];
int degrees = [[trapObject objectForKey:DEGREES] intValue];
[trapEntity setAlarmDistance:[NSNumber numberWithInt:alarmDistance]];
[trapEntity setType:[NSNumber numberWithInt:type]];
[trapEntity setRoadNumber:[NSNumber numberWithInt:roadNumber]];
[trapEntity setTrapID:[NSNumber numberWithInt:trap_id]];
[trapEntity setPolys:[NSNumber numberWithInt:polys]];
[trapEntity setDegrees:[NSNumber numberWithInt:degrees]];
// Boolean
BOOL isActive = [[trapObject objectForKey:ISACTIVE] integerValue] == 1 ? YES : NO;
[trapEntity setIsActive:[NSNumber numberWithBool:isActive]];
// Float
float lat = [[trapObject objectForKey:LAT] floatValue];
float lon = [[trapObject objectForKey:LON] floatValue];
[trapEntity setLat:[NSNumber numberWithFloat:lat]];
[trapEntity setLon:[NSNumber numberWithFloat:lon]];
// NSString
[trapEntity setDirection:[trapObject objectForKey:DIRECTION]];
[trapEntity setTrapDescription:[trapObject objectForKey:DESCRIPTION]];
[trapEntity setPoly0:[trapObject objectForKey:POLYGON_A]];
[trapEntity setPoly1:[trapObject objectForKey:POLYGON_B]];
[trapEntity setPoly2:[trapObject objectForKey:POLYGON_C]];
[trapEntity setPolygonAzimut1:[trapObject objectForKey:POLYGON_A_AZIMUTH]];
[trapEntity setPolygonAzimut2:[trapObject objectForKey:POLYGON_B_AZIMUTH]];
[trapEntity setPolygonAzimut3:[trapObject objectForKey:POLYGON_C_AZIMUTH]];
// etc. for all properties ...
if (![self.managedObjectContext save:&error])
NSLog(@"HANDLE ERROR WHEN SAVING THE OBJECT");
success = false;
我很高兴知道如何正确更新,因为我现在也缺少此功能。
编辑: 多亏了马丁,代码就像一个魅力。
【问题讨论】:
你说“现在,函数添加第一个对象,然后一遍又一遍地转到'更新'”你的更新函数在哪里? 更新应该在'if (success)'中,因为不知道怎么做,我还没有构建。 【参考方案1】:我不确定这是否是您的问题的原因,但您正在检查错误 条件或空结果是错误的。应该是
BOOL success = true;
Trap *trap = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:self.fetchRequest error:&error];
if (results == nil)
NSLog(@"HANDLE ERROR");
success = false;
else if ([results count] == 0)
NSLog(@"NOTHING TO UPDATE | ADD NEW");
trap = [NSEntityDescription insertNewObjectForEntityForName:@"Trap" inManagedObjectContext:self.managedObjectContext];
else
NSLog(@"UPDATE EXISTING OBJECT");
trap = result[0]; // There should be only one object for the ID.
if (trap != nil)
// Set properties for new or existing object ...
[trap setTrapID:[NSNumber numberWithInt:trap_id]];
// etc. for all properties ...
if (![self.managedObjectContext save:&error])
NSLog(@"HANDLE ERROR WHEN SAVING THE OBJECT");
success = false;
executeFetchRequest
返回
nil
如果发生错误,并且
如果未找到匹配对象,则为空数组。
【讨论】:
像魅力一样工作,谢谢!你能帮我如何更新/修改? 'trapObject' 每次都不同。 感谢您的帮助!我用你的答案编辑了代码。我第一次得到“没什么可更新的 | ADD NEW',其余时间我得到'UPDATE EXISTING OBJECT',然后用户界面卡住了,我在数据库中只看到一条记录。 @IdanMoshe:抱歉,但我不知道您的 UI 为何会卡住 :-) 请注意,您应该从代码中删除旧的trapEntity = [[self.managedObjectContext executeFetchRequest:self.fetchRequest error:&error] lastObject];
行。
奇怪。也许在调试器中单步执行并检查会发生什么。建议:验证int trap_id = ...
是否分配了正确的值。 (ID
是否与 @"trapID"
相同?)。 NSLog 谓词和获取请求。 NSLog 新创建的 Trap 对象,检查 ID 是否设置正确。以上是关于对 CoreData 执行添加/更新时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 NSPredicate 从 NSFetchedResultscontroller 更新 NSManagedObject 时出现 CoreData 错误
集成 RestKit 和 MagicalRecord 时出现 CoreData 轻量级迁移错误