【发布时间】:2014-11-06 20:49:35
【问题描述】:
我已经有这个问题好几天了,这真的很令人沮丧。我一直在检查我的代码,一遍又一遍地尝试不同的东西并一直遇到同样的问题。只有 50% 的情况不会发生这种情况总是。这使得它更难..
问题,
我正在将 3 个 csv 文件中的数据解析到我的核心数据,其中 2 个文件解析总是顺利进行,但中间/第二个文件总是发生崩溃的地方,因此,这将是该文件和 managedObjectContext 类的地址对于这个文件。
错误信息
CoreData: error: Serious application error.
Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.
-[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2014-09-12 11:27:06.115 AppName[210:3907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
因此,在我的 FetchData 课程中,我尝试以不同的方式解决问题。
- 首先,我更改了 .csv 文件并将 N/A 插入到所有空的字段/单元格中。
- 其次,我正在检查我的 FetchData 类,如果它没有任何值,请保存 N/A。
- 第三,在我触发解析数据的视图控制器中,我现在在我的核心数据中为这 3 个实体分离了三个不同的属性。
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContextGI;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContextVA;
这可能有点疯狂或其他什么,但我真的需要解决这个问题,所以尝试任何可能的解决方案或方法总是好的,我认为。
ViewController 调用函数来执行解析..
//at the beginning of my model
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
-(IBAction)myLoadingTask:(id)sender{
dispatch_async(kBgQueue, ^{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *savedValue = @"";
if([[userDefaults stringForKey:@"dataFetched"] length] > 0){
savedValue = [userDefaults stringForKey:@"dataFetched"];
}
// if the csv files data hasn't been fetch it, then fetch it
if([savedValue length] == 0){
FetchData *fd = [[FetchData alloc] initWithManagedContext:self.managedObjectContext];
// fetching benefits data
[fd beginParser];
FetchGIBillData *fdGI = [[FetchGIBillData alloc] initWithManagedContext:self.managedObjectContextGI];
// fetching gi bill data
[fdGI beginParser];
FetchVAPhones *fdVA = [[FetchVAPhones alloc] initWithManagedContext:self.managedObjectContextVA];
// fetching va phones
[fdVA beginParser];
NSString *valueToSave = @"saved";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"dataFetched"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
});
}
这是我的 Core Data 模型函数等等.. 我已经检查它是否为空保存 N/A 等等.. 我所有的我实体中的属性是 strings
#define GIBILL_FILENAME @"gi_bill_data"
int numOfEntries;
- (id)initWithManagedContext:(NSManagedObjectContext*)managedObjectContext
{
self.managedObjectContext = managedObjectContext;
arrayOfRecords = [[NSMutableArray alloc] init];
numOfEntries=0;
return self;
}
- (void) beginParser
{
if (self.managedObjectContext == nil){
// Error: Must pass in NSManagedObjectContext
return;
}
NSString *filePath = [[NSBundle mainBundle] pathForResource:GIBILL_FILENAME ofType:@"csv"];
NSInputStream *stream = [NSInputStream inputStreamWithFileAtPath:filePath];
NSStringEncoding encoding = NSUTF8StringEncoding;//NSWindowsCP1250StringEncoding;
CHCSVParser *parser = [[CHCSVParser alloc] initWithInputStream:stream usedEncoding:&encoding delimiter:','];
parser.delegate = self;
[parser parse];
// uncomment to update data x amount of dates
//[self checkDateForRefreshCSV:parser];
}
** 这是保存的地方!! *
#pragma mark - Data Add
/**
* addRows
* @param parser: the CHCSV parser that will parse if required refresh
* @brief: add the row to ths managedObjectContent DB. All values saved.
*/
- (void) addRows:(CHCSVParser *)parser
{
int i = -1;
if ([arrayOfRecords count] == 0) return;
GIBill *data = [NSEntityDescription
insertNewObjectForEntityForName:@"GIBill"
inManagedObjectContext:self.managedObjectContext];
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.facility_code = [arrayOfRecords objectAtIndex:i];
else
data.facility_code = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.institution = [arrayOfRecords objectAtIndex:i];
else
data.institution = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.city = [arrayOfRecords objectAtIndex:i];
else
data.city = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.state = [arrayOfRecords objectAtIndex:i];
else
data.state = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.country = [arrayOfRecords objectAtIndex:i];
else
data.country = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.bah = [arrayOfRecords objectAtIndex:i];
else
data.bah = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.poe = [arrayOfRecords objectAtIndex:i];
else
data.poe = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.yr = [arrayOfRecords objectAtIndex:i];
else
data.yr = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.gibill = [arrayOfRecords objectAtIndex:i];
else
data.gibill = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 0)
data.cross = [arrayOfRecords objectAtIndex:i];
else
data.cross = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.grad_rate = [arrayOfRecords objectAtIndex:i];
else
data.grad_rate = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.grad_rate_rank = [arrayOfRecords objectAtIndex:i];
else
data.grad_rate_rank = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.default_rate = [arrayOfRecords objectAtIndex:i];
else
data.default_rate = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.avg_stu_loan_debt = [arrayOfRecords objectAtIndex:i];
else
data.avg_stu_loan_debt = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.avg_stu_loan_debt_rank = [arrayOfRecords objectAtIndex:i];
else
data.avg_stu_loan_debt_rank = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.indicator_group = [arrayOfRecords objectAtIndex:i];
else
data.indicator_group = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.salary = [arrayOfRecords objectAtIndex:i];
else
data.salary = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.zip = [arrayOfRecords objectAtIndex:i];
else
data.zip = @"N/A";
if([[arrayOfRecords objectAtIndex:++i] length] > 2)
data.ope = [arrayOfRecords objectAtIndex:i];
else
data.ope = @"N/A";
NSError *error;
[self.managedObjectContext save:&error];
}
好吧,我发布了我认为该问题最相关的代码。如果需要其他内容或有关问题的更多详细信息,请告诉我,我会提供它..
提前致谢!
【问题讨论】:
-
添加异常断点并检查它在哪里插入null。
-
你正在使用旧的 Core Data 并发模型跨线程访问这些上下文,这会导致很多问题。
-
旧的核心数据并发模型是什么意思? @quellish
-
您正在使用线程限制。当您创建 NSManagedObjectContexts 时,您使用的是“init”,而不是带有 NSPrivateQueueConcurrencyType 或 NSMainQueueConcurrencyType 参数的“initWithConcurrencyType:”。这意味着您的 NSManagedObjectContext 只能在创建它的线程中使用。您在一个地方创建上下文,然后将其传递给使用并发调度队列的东西 - 这将根据需要创建尽可能多的线程。线程约束并发模型已经过时了一段时间。
-
哦!!!!我应该在我的 bg 线程中创建它吗? @quellish
标签: ios objective-c csv core-data