Swift CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。
Posted
技术标签:
【中文标题】Swift CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。【英文标题】:Swift CoreData: error: Serious application error. Exception was caught during Core Data change processing. 【发布时间】:2015-11-06 08:52:19 【问题描述】:我正在 ios 上编写一个程序,但我正面临这个错误:
2015-11-06 10:57:24.289 NETFNET[2503:976392] CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。这通常是 NSManagedObjectContextObjectsDidChangeNotification 观察者中的一个错误。 -[__NSCFSet addObject:]: 尝试用 userInfo (null) 插入 nil 2015-11-06 10:57:24.293 NETFNET[2503:976392] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFSet addObject:]:尝试插入 nil”
我想,我想从主线程和后台线程同时访问数据库。我见过很多针对 Objective C 的解决方案,但没有针对 Swift 的解决方案(我不知道 Objective C ...)。不幸的是,我不知道如何使用 Grand Central Dispatch,事实上,我的程序并不真正需要几个踏板(我的意思是它需要它,但是如果某个线程一次从一个函数中丢失信息,那么没有什么不好的发生)。我只想在 Swift 1 或 2 上有稳定的程序,所以我会感谢任何帮助。
【问题讨论】:
绝大多数 iOS 和 OS X 应用程序和库都是用 ObjectiveC 编写的。你至少应该学会阅读ObjectiveC,不管你能不能用它编写功能代码。 @JodyHagins 那条评论根本没有帮助。 也许...我只是想找到一个简单的解决方案... 【参考方案1】:您需要创建一个私有队列并发类型的私有 NSManagedObjectContext,并在后台线程上操作时使用它来访问 CoreData。
所以假设我需要在后台运行数据库操作,我可以将该工作分派到后台线程
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0),
//call your background operation.
)
然后在后台操作我可以创建一个私有的NSManagedObjectContext为
let moc = … //Our primary context on the main queue
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = moc
privateMOC.performBlock
//operations
do
try privateMOC.save()
catch
fatalError("Failure to save context: \(error)")
在多线程上实现核心数据操作之前,请阅读 Apple 的 CoreData Concurrency Guide 以获得良好的理解。
【讨论】:
访问数据库通常是通过异步连接到服务器(发布请求,像这样:let task = session.dataTaskWithRequest(requestToServer, completionHandler: data, response, error -> Void in //连接到数据库 ) 还不够吗? @MosTelecom 否,这意味着您与 db 的连接将在单独的线程上异步运行,但您需要确保它不使用主托管对象上下文。这将有助于防止同时通过同一个 moc 访问数据库。 @Alex 我也面临同样的问题。你解决了这个问题吗?请告诉我。我尝试了很多方法,但我无法解决这个问题。 @Mohanaraj.C 看,我可以向您推荐的一件事是将您的项目升级到 Swift 4.1 并将应用程序的最低版本升级到 iOS 10.0,因为 CoreData 中的这个版本可用 NSPersistentContainer。它将取代您当前的 CoreDataStack,并允许您避免崩溃。 @Alex 目前我正在使用 swift 4.1 和最低版本的应用程序 10.0,但我仍然只在一段时间内面临崩溃问题。错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。这通常是 NSManagedObjectContextObjectsDidChangeNotification 观察者中的一个错误。 *** 集合 <__nscfset:> 在枚举时发生了突变。与 userInfo (null)【参考方案2】:非常好。我试过了,对我来说效果很好。 非常感谢。
以前的代码:
do
try CDHelper.shared.context.save()
catch let error as NSError
// Error mesajlarını ekle!!
print("Could not fetch \(error), \(error.localizedDescription)")
print("Could not fetch \(error), \(error.localizedFailureReason)")
// MARK: - CONTEXT
lazy var context: NSManagedObjectContext =
let moc = NSManagedObjectContext(concurrencyType:.MainQueueConcurrencyType)
moc.persistentStoreCoordinator = self.coordinator
return moc
()
// MARK: - MODEL
lazy var model: NSManagedObjectModel =
return NSManagedObjectModel(contentsOfURL:self.modelURL)!
()
// MARK: - COORDINATOR
lazy var coordinator: NSPersistentStoreCoordinator =
return NSPersistentStoreCoordinator(managedObjectModel:self.model)
()
lazy var modelURL: NSURL =
let bundle = NSBundle.mainBundle()
if let url = bundle.URLForResource("Model", withExtension: "momd")
return url
print("CRITICAL - Managed Object Model file not found")
abort()
()
你应该这样修改代码:
let moc = NSManagedObjectContext(concurrencyType:.MainQueueConcurrencyType)
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = moc
privateMOC.performBlock(
do
try privateMOC.save()
catch
fatalError("Failure to save context: \(error)")
)
【讨论】:
【参考方案3】:只是在里面调用你的 CoreData 函数
DispatchQueue.main.async
...
为我工作
【讨论】:
【参考方案4】:您可以为此创建一个扩展并将save()
函数包装成这样的东西,因此您只需要使用此函数而不是save()
:
extension NSManagedObjectContext
func update() throws
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = self
context.perform(
do
try context.save()
catch
print(error)
)
【讨论】:
以上是关于Swift CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。的主要内容,如果未能解决你的问题,请参考以下文章
CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常
CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常
如何解决由于 iCloud 合并而导致的“CoreData:错误:严重的应用程序错误”?
Swift 3.0 Coredata - Appdelegate & managedObjectContext 抛出 EXC_BAD_ACCESS 错误