0

我有一个在后台注册位置更新的应用程序。每当更新位置时,我都需要遍历一个NSMutableArray坐标来查看哪个坐标离用户最近。

有时出于记忆的原因,手机会杀死我的应用程序(尽管它仍然注册以接收位置更新),以及我NSMutableArray的坐标。

因此,每当位置更新出现时,我必须检查我NSMutableArray的坐标是否仍然存在,如果没有,我想从 SQLite 表中重新填充它。

在运行了一些测试之后,似乎没有从 SQLite 表重新填充我的坐标数组,这是我在位置更新时运行的代码:

bgTask = [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{[[UIApplication sharedApplication] endBackgroundTask:bgTask]}];

if(coordArray == nil || coordArray.count == 0)
{
    [self readCoordinatesFromDatabase];
}
else
{
    //Check which coordinate is closest to the user.
}

if(bgTask != UIBackgroundTaskInvalid)
{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}

在这种情况下,我是否不允许从 SQLite 读取数据?

每当发生位置更新时,我绝对需要能够通过我的坐标数组(在后台),即使应用程序在一段时间后被杀死,我该怎么做?

4

3 回答 3

4

猜测你是直接和 SQLite 对话,你没有理由不能在后台运行它。您是直接编写 C 代码来与 SQLite 对话还是使用库?

但是,如果您遇到内存问题,也许您应该将坐标保留在 SQLite 中,而不是将它们全部加载到内存中?

或者也许切换到 Core Data,这将极大地帮助解决内存问题并减少您为访问数据而编写的代码量。

将数据存储在 SQLite 中并使用数据库查找接近坐标将比每次进入新位置时循环遍历数组要高效得多。

更新 1

如果您的应用程序不在前面,它将最终被终止。

如果您使用后台位置更新,则操作系统会尝试让您继续运行,但这并不能保证。

如果你是一个有记忆力的坏公民,你被处决。将数据保存在磁盘上而不是内存中将在各方面有所帮助。它会减少你的内存,让你在操作系统中保持良好的状态,并增加你的应用程序在后台运行的机会。

不要将数据保存在内存中,将其保存在磁盘上。分析您的应用程序以使其内存消耗尽可能接近于零。

于 2013-05-30T15:26:34.957 回答
1
  1. 使用http://www.sqlite.org/download.html上的合并源编译您自己的 SQLite

    一个。添加sqlite3.c到您的项目并添加编译器标志-DSQLITE_ENABLE_RTREE=1(在 Build Phases > Compile Sources 下)

    湾。使用 RTree 创建一个表,使用类似于CREATE VIRTUAL TABLE location_index USING rtree(id, minX, maxX, minY, maxY) 您可以将所有位置放入location_index数据库并在数据库上执行地理空间查询以获取用户位置范围内的位置。有关在 SQLite 中使用 R*Tree 的更多信息:http ://www.sqlite.org/rtree.html

    C。正如马库斯所说,避免将所有观点都留在记忆中。不要将它们放在一个数组中。不要循环通过它们。将它们保存在数据库中,使用location_index表查询它们,并在必要时将它们转换回对象。

  2. 使用 FMDB 作为 SQLite 包装器,特别是使用 FMDatabaseQueue 以便您的数据库访问可以排队(通过多个线程安全访问),并且您可以使用 GCD 将 SQLite 的结果动态转换为对象,而不是在主线程上https://github.com/ccgus/fmdb

  3. 您不能“确保我的申请永远不会因任何原因而终止”。用户可以终止您的应用程序(例如双击主页按钮,点击红色圆圈),如果您是坏公民,操作系统应该有权终止您的应用程序。不要做坏公民,尽可能降低内存开销。

于 2013-05-30T20:59:47.287 回答
-1

所有 SQLite 调用必须从同一个线程进行。你可以在这里找到一个例子:https ://github.com/AaronBratcher/ABSQLite

EDIT调用必须同步,如下所述。

于 2013-07-11T14:31:45.110 回答