- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经阅读了有关此错误的所有内容,但仍然无法确定为什么它会在我的应用程序中发生。
使用后台上下文保存多个 Core Data 对象时出现以下错误:
*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“保存前无法处理挂起的更改。100 次尝试后上下文仍然是脏的。通常这种递归脏化是由错误的验证方法引起的、-willSave 或通知处理程序。
在下面的代码中,ArticleManager
的addArticle
在主线程中循环调用。可能有 0-200 多篇文章要添加。此错误通常发生在文章计数 100-150 之间。
//ArticleManager.m
-(id)init
{
... //normal init stuff
dispatch_queue_t request_queue = dispatch_queue_create("com.app.articleRequest", NULL);
}
-(void) addArticle:(Article *)article withURLKey:(NSString *)url
{
//check if exists
if ([downloadedArticles objectForKey:url] == nil && article != nil)
{
//add locally
[downloadedArticles setObject:article forKey:url];
//save to core data
SaveArticle *saveArticle = [[SaveArticle alloc] init];
[saveArticle saveArticle:article withURL:url onQueue:request_queue];
}
}
//SaveArticle.m
@implementation SaveArticle
@synthesize managedObjectContext;
@synthesize backgroundContext;
-(id)init
{
if (![super init]) return nil;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
backgroundContext = [[NSManagedObjectContext alloc] init];
[backgroundContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];
return self;
}
-(void)saveArticle:(Article *)article withURL:(NSString *)url onQueue:(dispatch_queue_t)queue
{
//save persistently in the background
dispatch_async(queue, ^{
ArticleCache *articleCacheObjectModel = (ArticleCache *)[NSEntityDescription insertNewObjectForEntityForName:@"ArticleCache" inManagedObjectContext:backgroundContext];
if (article != nil)
{
[articleCacheObjectModel setArticleHTML:article.articleHTML];
[articleCacheObjectModel setUrl:url];
NSError *error;
//Save the background context and handle the save notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:backgroundContext];
if(![backgroundContext save:&error]) //ERROR OCCURS HERE, after many saves
{
//This is a serious error saying the record
//could not be saved. Advise the user to
//try again or restart the application.
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:backgroundContext];
}
});
}
/* Save notification handler for the background context */
- (void)backgroundContextDidSave:(NSNotification *)notification {
/* Make sure we're on the main thread when updating the main context */
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
withObject:notification
waitUntilDone:NO];
return;
}
/* merge in the changes to the main context */
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
@end
最佳答案
好的,所以阅读官方文档还是有点用的。
来自 Apple(强调我的):
Concurrency
Core Data uses thread (or serialized queue) confinement to protect managed objects and managed object contexts (see “Concurrency with Core Data”). A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method. You should not, therefore, initialize a context on one thread then pass it to a different thread. Instead, you should pass a reference to a persistent store coordinator and have the receiving thread/queue create a new context derived from that. If you use NSOperation, you must create the context in main (for a serial queue) or start (for a concurrent queue).
所以我的问题是我在主线程上初始化了后台上下文,但随后通过 dispatch_async
使用了 Grand Central Dispatch,它在后台线程上执行保存(使用创建的上下文主线程)。
我通过将上下文初始化添加到背景 block 来修复它:
-(void)saveArticle:(Article *)article withURL:(NSString *)url onQueue:(dispatch_queue_t)queue
{
//save persistently in the background
dispatch_async(queue, ^{
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init];
[backgroundContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];
ArticleCache *articleCacheObjectModel = (ArticleCache *)[NSEntityDescription insertNewObjectForEntityForName:@"ArticleCache" inManagedObjectContext:backgroundContext];
if (article != nil)
{
[articleCacheObjectModel setArticleHTML:article.articleHTML];
[articleCacheObjectModel setUrl:url];
NSError *error;
//Save the background context and handle the save notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:backgroundContext];
if(![backgroundContext save:&error])
{
//This is a serious error saying the record
//could not be saved. Advise the user to
//try again or restart the application.
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:backgroundContext];
}
});
}
关于ios - 在后台上下文中保存核心数据时出现 NSInternalInconsistencyException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11871470/
我的 iOS 应用程序出现奇怪的错误。从昨天开始一切都运行良好,今天我对一个与 AppDelegate 无关的 View Controller 做了一些改进,当我试图测试我在模拟器上所做的更改时,我得
所以,我正在尝试一下 iOS 编程。时间不多,但我已经推迟学习太久了。但我被这个奇怪的问题困扰了两天。当我尝试将单元格添加到我的 collectionView 时,出现以下错误。 'NSInterna
我的应用程序发生了奇怪的崩溃(仅限 iPad 的 9.x),我不确定如何调试它,因为日志无助于发现正在发生的事情。 最奇怪的是日志显示Auto layout internal error ,但我的应用
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid updat
我想在 swift 中创建一个弹出窗口,并在用户单击按钮时显示它。我不使用 Storyboard , View 是通过编程创建的。 class CreateNoticePopupViewControl
我在仅限 iOS 12 的 crashlytics 上遇到此崩溃。 有人知道这是什么吗?看起来与推送通知相关,但我们的应用中还没有。 致命异常:NSInternalInconsistencyExcep
我已经阅读了有关此错误的所有内容,但仍然无法确定为什么它会在我的应用程序中发生。 使用后台上下文保存多个 Core Data 对象时出现以下错误: *** 由于未捕获的异常“NSInternalInc
我正在尝试从 UITableView 中删除行 -(void) closePickerViewRow:(id) sender { if(self.pickerIsShown && [self.
我在 IOS 上使用 PhoneGap 2.9.0 并为 iPhone5 构建应用程序。 我正在尝试更改启动画面,我遵循了 phonegap 解释 我的行动: 1. 在 iPhone project
对,我有 5 次观看。其中一个 View 称为 RecordViewController。 (RecordViewController 导致错误)我可以很好地切换 View 。但是一旦我进入记录 Vi
在搜索解决方案后我无法解决这个问题,我有这段代码来列出核心数据中的数据: import UIKit import CoreData class ViewControllerClass: UITable
我遇到了一个问题,我有一个忘记密码选项,我在其中放置了一个带有输入字段的 UIAlertView。 UIAlertView *alertView = [[UIAlertView alloc] init
我想用 Objective-C 做一个带有表搜索的 iOS 应用程序。我试过这个项目: https://github.com/versluis/Table-Search-2015 现在我尝试在导航 V
我在 View Controller 之间切换时遇到问题。 我的 md360AppDelegate.h header 如下所示 #import @class md360ViewController;
更新方法: override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingS
每当我尝试使用 AVPlayer 从 url 流式传输歌曲时,我都会收到 NSInternalInconsistencyException 错误。我在结构上制作了一个全局流播放器,以便我的流播放器可以
我正在尝试向我的应用添加容器 View 。但是,它不断崩溃并出现以下错误: 'NSInternalInconsistencyException',原因:'containerView 是必需的。' 我做
尝试保留(更新)标识对象 (persistIdentity:error:) 时版本不匹配失败。对象版本=1229,持久版本=1230。 #10. Crashed: com.twitter.crashl
更新:看来我设法识别了单元格,所以原来的问题解决了。但是现在,截断相同的代码后,出现以下错误: 2012-10-31 15:21:41.857 Laktase[22658:11603] -[NSMan
我有这段代码试图在后台获取 HealthKit 数据。当我第一次运行该应用程序时,代码运行良好,但如果我手动执行后台提取(使用调试命令),我会抛出一个异常并显示一个错误,内容为 reason: 'th
我是一名优秀的程序员,十分优秀!