- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序可能会在运行时创建/删除数以千计的托管对象。我已将辅助 NSManagedObjectContext
s(MOCs) 与 NSPrivateQueueConcurrencyType
和 NSOperation
一起使用,以使应用程序的响应速度更快,并且大多数部分运行良好。但是当我按下 ⌘Q 并且如果未保存的对象数量很大时,应用程序会在窗口关闭之前挂起一段时间(沙滩球一直在旋转......)。
如何让窗口立即消失,在 MOC 保存之前?我试图在 AppDelegate
的 applicationShouldTerminate
中插入 window.close()
,但没有效果。
我的删除代码没什么特别的,只是层次结构非常大。有点像
let items = self.items as! Set<Item>
Group.removeItems(items)
for i in items {
self.managedObjectContext?.deleteObject(i)
}
Item
是一个分层实体。 Group
与项具有一对多关系。removeItems
由 CoreData 使用 @NSManaged
生成。
非常感谢。
更新
我尝试了以下代码,保存仍然阻塞了 UI。
@IBAction func quit(sender: AnyObject) {
NSRunningApplication.currentApplication().hide()
NSApp.terminate(sender)
}
func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply
{
let op = NSBlockOperation { () -> Void in
do {
try self.managedObjectContext.save()
} catch {
print("error")
}
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
NSApp.replyToApplicationShouldTerminate(true)
})
}
op.start()
return .TerminateLater
}
当创建/删除的托管对象数量很大时,这不会让窗口先关闭。
然后我按照@bteapot 的建议更改为以下内容。还是没有效果。窗口仍然不会立即关闭。
@IBAction func quit(sender: AnyObject) {
NSRunningApplication.currentApplication().hide()
NSApp.terminate(sender)
}
func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply {
let op = NSBlockOperation { () -> Void in
self.managedObjectContext.performBlock({ () -> Void in
do {
try self.managedObjectContext.save()
} catch {
print("errr")
}
})
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
NSApp.replyToApplicationShouldTerminate(true)
})
}
dispatch_async ( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
{() -> Void in
op.start()
})
return .TerminateLater
}
最后我解决了这个问题,虽然 UI 仍然被阻塞有时,即使使用相同的测试数据也是如此。
使用的方法可以在这里找到:https://blog.codecentric.de/en/2014/11/concurrency-coredata/ , Core Data background context best practice , https://www.cocoanetics.com/2012/07/multi-context-coredata/
首先,我用 .PrivateQueueConcurrencyType
创建了一个 backgroundMOC
lazy var backgroundMOC : NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
let moc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
moc.persistentStoreCoordinator = coordinator
moc.undoManager = nil
return moc
}()
然后把它变成原来的 moc。
lazy var managedObjectContext: NSManagedObjectContext = {
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
// managedObjectContext.persistentStoreCoordinator = coordinator
managedObjectContext.parentContext = self.backgroundMOC
managedObjectContext.undoManager = nil
return managedObjectContext
}()
两种保存方式。
func saveBackgroundMOC() {
self.backgroundMOC.performBlock { () -> Void in
do {
try self.backgroundMOC.save()
NSApp.replyToApplicationShouldTerminate(true)
} catch {
print("save error: bg")
}
}
}
func saveMainMOC() {
self.managedObjectContext.performBlock { () -> Void in
do {
try self.managedObjectContext.save()
self.saveBackgroundMOC()
} catch {
print("save error")
}
}
}
将 applicationShouldTerminate()
更改为
func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply {
if !managedObjectContext.commitEditing() {
NSLog("\(NSStringFromClass(self.dynamicType)) unable to commit editing to terminate")
return .TerminateCancel
}
if !managedObjectContext.hasChanges {
return .TerminateNow
}
saveMainMOC()
return .TerminateLater
它这么慢的原因是我使用的是 NSXMLStoreType
而不是 NSSQLiteStoreType
。
最佳答案
退出应用程序可能需要一段时间,因为它会首先清空队列中的进程。你想立即放弃丢弃父或子 MOC 中的所有内容吗?但这会导致数据丢失。
如果你有多窗口应用程序,那么只关闭窗口而不退出应用程序。
此外,如果您管理得当,处理和保存数千个条目的时间不应超过 5 秒。您的代码中可能存在一些漏洞,请尝试使用 Instruments 和 CoreData 分析器工具进行优化,这将帮助您了解它消耗的时间量。
要隐藏窗口,您可以使用下面的方法,所有核心数据处理都将在后台进行,一旦一切完成,应用程序将终止。
[self.window orderOut:nil];
关于objective-c - CoreData 应用程序退出时间过长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34434478/
按照我目前安排代码的方式,下一行将为各种托管对象上下文运行。一些获取的实体将具有“complededDate”,而其他实体将没有“completedDate”属性。 let task = retrie
我在 import CoreData 的应用程序委托(delegate)中遇到此错误。据我所知,这是因为我将一个项目命名为 coreData。但是我更改了项目的名称,然后将其删除,并且删除了 /Lib
我想将记录保存在数组中并从 CoreData 中删除它们。我尝试过使用 NSCopying 但似乎 copyWithZone 不适用于 NSManagedObject。我真的很困惑,任何帮助将不胜感激
有时我的项目中很少会出现错误(比如每第 100 个请求)。我的一些 CoreData 的请求有 data:我无法使用该数据。我真的不明白为什么会发生这种情况以及如何防止这种行为。 错误数据输出示例:
如果您使用 Xcode 创建一个新项目并告诉它在您创建项目时创建一个 CoreData 模板,则您不需要 #import 在使用 ManagedObjects 的类中。 我已经将 Core Data
我对 SQLCipher 数据库加密和 CoreData 有疑问:当我将持久存储协调器与 SQLCipher 一起使用时,它总是在第一次应用程序重新启动后因一对多关系故障而崩溃。因此,当我第一次启动该
我有一个想要添加 iCloud 支持的应用程序。此应用程序从服务器加载数据,并将数据存储在 CoreData 中,以便 NSFetchedResultsController可以管理UITableVie
我正在从 coredata 表 STUDENT 中获取数据,并使用 Array 在 tableview 中显示所有学生姓名。在选择任何一个学生姓名后(点击 tableViewCell),它会从另一个表
我在构建过程中收到以下错误。 “API 滥用:尝试序列化非拥有协调器上的存储访问(PSC = 0x7fb5ae208890,存储 PSC = 0x0)CoreData 为什么我的应用程序会出现 Cor
当将 iOS 6.0.1 上的 Core Data 托管对象上下文保存到 SQLite 存储时,我遇到了一个奇怪的“CoreData 不支持持久的跨存储关系”异常。它涉及模型中 Quotes 和 Ab
我的应用程序有两个选项卡栏...每个选项卡栏都将用户带到一个向他显示项目列表的 TableView Controller 。第一个 View 允许用户在数据库中记录条目。另一个选项卡/ View 从数
Objective-C (OC) 中使用 Core Data 是iOS应用开发中管理模型层对象的一种有效工具。Core Data 使用 ORM (对象关系映射) 技术来抽象化和管理数据。这不仅可以节省
我有一个名为visitDate的coredata属性 我想使用单独的选择器相互独立地设置日期和时间。 我意识到,当我设置时间时,我需要获取visitDate的现有日期、月份和年份,但只从NSDateP
我有这个代码示例演示如何更新核心数据中的对象,但是我遇到了一个小问题: // Retrieve the context if (managedObjectContext == nil) { m
我在 CoreData 中有一个包含整数值的列。在从中检索结果时,我希望将列值减去一个数字。 类似于:columnValue - someNumber(此数字由用户输入) 我知道我可能必须为此使用 N
有没有办法将 CoreData 模型文件(即实体描述:*.xcdatamodeld)导出到另一个项目。因为重新创建所有实体很无聊:-) 最佳答案 是的,只需将模型文件本身添加/复制到新项目中,就像任何
我使用核心数据编写了 iPhone 应用程序。当我在模拟器中运行应用程序时,它崩溃并出现以下错误: 2010-02-12 17:24:22.359 CrData[46122:4503] Unresol
我是 CoreData 的新手,在我的 iPhone 应用程序中,我想知道如何保存一些文本,然后将其重新加载。但诀窍是,当 UIDatePicker 中的日期与我相同时加载它。像日历一样保存它。 更新
我正在寻找在 CoreData 中编写一些基本查询的方法,但文档中没有示例。以下是我的查询: 我有一个费用对象,它有一个费用金额字段。 费用可以链接到 ExpenseCategory 对象。 Expe
我在标题中使用“单例”一词时可能存在术语不正确的情况。我现在正在寻找一种好的技术。我有一个名为 user 的实体,它存储用户登录的数据,例如用于发出服务器请求的 session key 。我只希望这些
我是一名优秀的程序员,十分优秀!