我在后台线程上使用批量更新更新核心数据时遇到问题。在下面的代码中,我使用主线程通过进度 View 和调用 appdelegate 中方法的字符串来通知用户。但是,如果我在随机数量的数据中的 NSEntity 行中遇到错误访问错误,其中我有数千个对象需要更新。如果我取消注释 NSLOG,我在下面指出没有错误,或者如果我评论主线程没有错误,或者,如果我不通过批量更新,而是使用批量更新,那么也不会出现错误。如果我评论自动释放池也会出现错误。请有人帮助我吗?
提前致谢,
干杯, 什拉万
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
NSUInteger iterator = 1;
for (int i = 0; i < totalNo; i++) {
NSDictionary *alertResult = [[alertResultList objectAtIndex:i] retain];
if (alertResult == nil) {
continue;
}
//managedObjectContext = [appDelegate.managedObjectContext retain];
NSLog(@"Object Count:%u", [[managedObjectContext insertedObjects]count]);
AlertResult *result = (AlertResult *)[NSEntityDescription
insertNewObjectForEntityForName:@"AlertResult"
inManagedObjectContext:managedObjectContext];
[result setUserName:@"A"];
iterator++;
//When count reaches max update count we are saving and draining the pool and resetting the pool
if (iterator == kUploadCount) {
if ([self update] == NO) {
// If unable to update Alert results in the Core Data repository, return
// a custom status code.
statusCode = -1;
}
[managedObjectContext reset];
[tempPool drain];
tempPool = [[NSAutoreleasePool alloc] init];
iterator = 0;
}
//Adding code to change the display string for the lock view to notify user
float count1 = (float)(counter/totalAlerts);
counter = counter + 1.0f;
NSString *dispStr = [NSString stringWithFormat:@"%f",count1];//[NSString stringWithFormat:@"Loading %d out of %d alerts",(i+1),totalAlerts];
NSString *dispMess = [NSString stringWithFormat:@"Alerts %d of %d",(i+1),totalNo];
[self performSelectorOnMainThread:@selector(changeLockScreenMessageWith:) withObject:[NSArray arrayWithObjects:dispStr,dispMess, nil] waitUntilDone:YES];
//NSLog(@"count"); /* If I uncomment this line code runs fine */
[alertResult release];
alertResult = nil;
}
//If count is inbetween the update limit we are updating and we are draining the pool
if (iterator != 0) {
if ([self update] == NO) {
// If unable to update Alert results in the Core Data repository, return
// a custom status code.
statusCode = -1;
}
[managedObjectContext reset];
//[tempPool drain];
}
//Out side the previous method
- (BOOL)update {
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"%@", [error userInfo]);
return NO;
}
return YES;
}
最佳答案
您所描述的这种崩溃的最可能原因是跨线程使用managedObjectContext
。 ManagedObjectContext 不是线程安全的。您必须为每个线程创建一个新的 MOC。我假设 ManagedObjectContext 是一个 ivar;你不应该像这样直接访问你的ivars(除了在init和dealloc中)。始终使用访问器来为您处理内存管理。
NSLog
使其崩溃的原因是 NSLog
极大地改变了该函数的时间,并且存在竞争条件。
关于iphone - 使用线程批量更新核心数据时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7174994/