首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Coredata非常慢;快速

Coredata非常慢;快速
EN

Stack Overflow用户
提问于 2016-03-26 21:36:51
回答 2查看 3.5K关注 0票数 10

我制作了一个iOS应用程序来跟踪该设备的全球定位系统路径。问题是,当我跟踪超过5分钟时,coredata需要很长时间来保存。我保存了一个名为session的对象,session有很多位置对象。位置对象是[纬度、经度]。

会话对象看起来像[名称:字符串,日期: nsdate,平均速度:双,高速:双,驱动公里:双,位置:[双,双]]

所以..。它能工作,但5分钟后。我想节省2到3分钟

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-26 22:23:30

如果您有许多相同类型的对象,那么Core数据自然需要很长时间才能保存。不管你做什么,都需要一段时间。您可以做的是将保存配置为在后台线程中放置位置,以避免冻结您的UI。

最简单的方法是为您的主上下文创建一个背景上下文。其思想是,主上下文将其数据保存到父上下文,父上下文负责将数据持久化到磁盘。基本上是这样的:

因为主上下文和父上下文都在内存中运行,所以从子上下文到父上下文的保存操作是快速的。一旦父对象拥有您的位置对象,它将保存在后台线程中。它可能还需要很长时间,但至少不应该冻结您的UI。

您可以在代码中配置如下所示:

代码语言:javascript
复制
lazy var parentContext: NSManagedObjectContext = {
    let moc = NSManagedObjectContext(concurrencyType:.PrivateQueueConcurrencyType)
    moc.persistentStoreCoordinator = self.coordinator
    return moc
}()

lazy var context: NSManagedObjectContext = {
    let moc = NSManagedObjectContext(concurrencyType:.MainQueueConcurrencyType)
    // moc.persistentStoreCoordinator = self.coordinator
    moc.parentContext = self.parentContext
    return moc
}()

context将是子上下文。您可以看到给它一个父上下文是多么容易。

然后,为了保存数据:

代码语言:javascript
复制
class func save(moc:NSManagedObjectContext) {

    moc.performBlockAndWait {

        if moc.hasChanges {

            do {
                try moc.save()
            } catch {
                print("ERROR saving context \(moc.description) - \(error)")
            }
        }

        if let parentContext = moc.parentContext {
            save(parentContext)
        }
    }
}

(代码取自Tim的“使用Swift学习iOS核心数据:动手指南”一书)。

票数 10
EN

Stack Overflow用户

发布于 2020-02-16 14:07:36

2020年更新。

基本上,必须使用,即“备用上下文”,即现在由核心数据提供的

所以core.container是你的容器..。很可能是从您的核心数据堆栈单例。

所以你的世界鸟类数据库的新数据来了。

代码语言:javascript
复制
let pm = core.container.newBackgroundContext()
pm.perform {
    for oneBudgie in someNewData {
        ... create your new CDBudgie entity ...
        ... take EXTREME care to use "pm" throughout ...
        ... take EXTREME care to NEVER use .viewContext throughout ...
    }
}

在循环过程中,

..。要非常小心,不要在该循环中使用.viewContext。只在循环中使用"pm“。如果您调用其他代码,请特别小心。

例如,假设您有一个实用例程,它“查找某一项”。

或者是一个简单地抓住主用户的实用例程。

这些实用例程可能只是使用通常的主上下文,core.container.viewContext

当您编写这样的实用程序例程时,只使用主上下文是很自然的,而无需考虑它。

但。在代码中,很容易在循环中意外地使用这样一个实用程序例程。

如果您这样做,应用程序将立即崩溃。

在循环中的代码中,您不能意外地在某个地方使用core.container.viewContext

您只能在循环中或任何最终被调用的代码中对任何CoreData使用"pm“,无论嵌套程度有多深,都可以在该循环中使用。

在创建了所有新项之后,您似乎正执行以下操作:

代码语言:javascript
复制
func bake() {
    self.performAndWait {
        if self.hasChanges {
            do {
                try self.save()
            }
            catch { print("bake disaster type 1 \(error)") }
        }

        // BUT SEE NOTES BELOW
        if core.container.viewContext.hasChanges {
            do {
                try core.container.viewContext.save()
            }
            catch { print("bake disaster type 2 \(error)") }
        }
        // BUT SEE NOTES BELOW
 
    }
}

就我所知道。没人知道,但据我所知。

因此,

代码语言:javascript
复制
let pm = core.container.newBackgroundContext()
pm.perform {
    for oneBudgie in someNewData {
        ... create your new CDBudgie entity ...
        ... be absolutely certain to only use 'pm' ...
    }
    pm.bake()
}

然而,在今天的实践中,您不需要对主要的上下文做任何事情:

"...and然后保存主上下文“的所有例子今天基本上都是错误的。

在今天的现实中,在99.9999%的情况下,您将使用.automaticallyMergesChangesFromParent = true,它现在工作得非常完美和顺利。(Example介绍了如何做到这一点。)

在上面的bake()示例中,如果您确实添加了几行打印行来检查第二次保存中发生了什么,您将看到.

...there绝不是要保存在主上下文中的任何东西!

因此,在实践中,你的烘焙程序很简单,

代码语言:javascript
复制
func bake() {
    self.performAndWait {
        if self.hasChanges {
            do {
                try self.save()
            }
            catch { print("bake disaster type 1 \(error)") }
        }
}

最后一点..。

注意,整个烘焙实际上是在一个performAndWait中调用的。但是,烘焙本身做的重要保存,在一个performAndWait

我确实知道,它的工作方式非常可靠。

(讨论这个问题的人很少)认为需要内在的问题。

但是:在我看来,您不需要(内部performAndWait )。

所以可以想象,烤蛋糕更简单-

代码语言:javascript
复制
func bake() {
    if self.hasChanges {
        do {
            try self.save()
        }
        catch {
            print("woe \(error)")
        }
    }
}

当我尝试这种形式的烘焙,它似乎工作得很好,没有问题。但是,对于核心数据,你必须经过多年的测试才能发现问题。

正如我在评论中提到的,我认为在互联网上大约有两个地方解释了这一点,@AndyIbanez原来的答案,以及这个更新的版本!

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36241172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档