由于 iOS 持久性商店问题和未从 Coredata 加载数据而导致应用程序崩溃
Posted
技术标签:
【中文标题】由于 iOS 持久性商店问题和未从 Coredata 加载数据而导致应用程序崩溃【英文标题】:Getting app crash by iOS Persistent store issue and data not loading from Coredata 【发布时间】:2015-04-08 11:44:33 【问题描述】:我来了
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObject persistentStore]: unrecognized selector sent to instance 0x3bebf50'
和
从核心数据加载数据时。我已经引用了链接ios Persistent store issue,但它并没有解决我的问题。数据也没有保存到tableview。 早些时候它正在加载,但由于数据量大,我使用了后台核心数据保存。但目前没有从数据库加载数据。我正在使用 NSFetchResultController 来获取数据。
-(void)updateThreadEntityWithSyncDetails:(NSMutableDictionary *)inDictionary
dispatch_queue_t backgroundQueue = dispatch_queue_create("backgroundQueueName", NULL);
NSString *loginUser=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];
AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSManagedObjectContext *contextforThread = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
contextforThread.parentContext = context;
[contextforThread performBlock:^
// AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
// NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThreadInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"userEmail == %@",loginUser];
NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"threadID == %@",[inDictionary valueForKey:@"thread"]];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[userPredicate, threadPredicate]];
[fetchRequest setPredicate:compoundPredicate];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil];
for (ThreadInfo *threadInfo in fetchedObjects)
if([[inDictionary allKeys] containsObject:@"userEmail"])
if([inDictionary valueForKey:@"userEmail"]!=[NSNull null])
threadInfo.userEmail=[inDictionary valueForKey:@"userEmail"];
if([[inDictionary allKeys] containsObject:@"secret_seed"])
if([inDictionary valueForKey:@"secret_seed"]!=[NSNull null])
threadInfo.threadSecret=[NSString stringWithFormat:@"%@",[inDictionary valueForKey:@"secret_seed"]];
if([[inDictionary allKeys] containsObject:@"r_key"])
if([inDictionary valueForKey:@"r_key"]!=[NSNull null])
threadInfo.remoteKey=[inDictionary valueForKey:@"r_key"];
if([[inDictionary allKeys] containsObject:@"solicitation"])
if([inDictionary valueForKey:@"solicitation"]!=[NSNull null])
threadInfo.solicitationID=[inDictionary valueForKey:@"solicitation"];
if([[inDictionary allKeys] containsObject:@"r_secret"])
if([inDictionary valueForKey:@"r_secret"]!=[NSNull null])
threadInfo.remoteSecret=[inDictionary valueForKey:@"r_secret"];
NSError *error;
if (![contextforThread save:&error])
NSLog(@"Could not insert to userInfo: %@", [error localizedDescription]);
[context performBlock:^
NSError *error;
if (![context save:&error])
NSLog(@"Could not insert to userInfo: %@", [error localizedDescription]);
];
];
// if (![context save:&error])
// NSLog(@"Could not update to threadInfo: %@", [error localizedDescription]);
//
Appdelegate
- (void)saveContext
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
#pragma mark - Core Data stack
- (NSManagedObjectContext *)managedObjectContext
if (_managedObjectContext != nil)
return _managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
// _managedObjectContext = [[NSManagedObjectContext alloc] init];
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
if (_managedObjectModel != nil)
return _managedObjectModel;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"IXCoreDataModel" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
if (_persistentStoreCoordinator != nil)
return _persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Inxed.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
/*
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
return _persistentStoreCoordinator;
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
FetchedResultsController
-(NSFetchedResultsController*)fetchedResultsController
if (_fetchedResultsController != nil)
return _fetchedResultsController;
NSString *loginUser=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];
AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThreadInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"threadDate" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"userEmail == %@",loginUser];
// NSPredicate *providerPredicate = [NSPredicate predicateWithFormat:@"isReceiver == YES"];
// NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[threadPredicate, providerPredicate]];
[fetchRequest setPredicate:threadPredicate];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:nil
cacheName:nil];
_fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
崩溃代码
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
ThreadInfo *info=[_fetchedResultsController objectAtIndexPath:indexPath];
if([info.isSystemMessage boolValue])// CRASH CoreData: error: NULL _cd_rawData but the object is not being turned into a fault
return 178+90+25;
else
return 178;
得到
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Only run on the main thread! with userInfo (null)
当滚动到最后一个单元格时,我也遇到了崩溃,单元格中没有任何内容。
【问题讨论】:
如果您将导入包装到上下文 performBlock 中是否有帮助? 此外,您是否知道保存上下文不会传播到持久存储,它只会保存一个级别:) 其实我不是很清楚。我的问题是将数据保存到核心数据应用程序变得很慢。所以我确实搜索了堆栈溢出并找到了需要使用多线程的解决方案。可以看到代码父子上下文。 @Muhsina Muhammed:请尝试添加异常断点。并让我们知道哪条线路导致了异常。你知道怎么做吗? 是的,但是您已经设置了上下文的并发类型,因此它现在已分配到另一个线程。删除您的调度块,而是将所有代码移动到后台上下文的 performBlock 方法中 【参考方案1】:确保将上下文保存在 performBlock 方法中,例如
[mainContext performBlock^
[mainContext save:&error];
];
另请参阅this thread
【讨论】:
是的,我做到了。但仍然没有从 coredata 获取和更新 tableview 的数据。 有时数据加载后出现此错误:CoreData: error: NULL _cd_rawData but object is not being turn into a fault以上是关于由于 iOS 持久性商店问题和未从 Coredata 加载数据而导致应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章