我正在寻找解决这个难题的最佳实践:
我的应用程序具有与 Core Data 相结合的文件导入/导出功能。这意味着当我将文件导入我的应用程序时,我会在 Core Data 中创建一个条目并将此文件复制到应用程序的私有(private)目录中。接下来,我处理该文件并从中创建一些其他文件,用于应用程序中的不同目的。对于 iPhone 3G 上的每个文件,这些繁重的计算需要大约 0.2 秒。
这意味着我在导入时正在处理某种“交易”。全部使用一个大的 FileImportOperation : NSOperation
完成它遍历所有必须导入的文件,并对列表中的每个文件执行繁重的导入工作。
问题是这样的:后台线程和 NSOperations 在没有事先警告的情况下被操作系统在几纳秒内杀死。只有主线程获得最多 5 秒的时间来快速保存一些工作并退出。
如何确保我永远不会在中途导入文件,使应用程序处于损坏或损坏状态?
在我看来,邪恶的问题是当用户退出应用程序时,后台线程(包括 NSOperation)会立即被杀死,而没有任何清理的机会。我试图通过仅在所有这些文件都已成功创建和保存的情况下编写托管对象来弥补这一点(请记住:每个导入的文件都会以不同的方式复制和处理多次以处理不同的事情)。但我仍然会以不完整的导入结束,从而破坏用户的磁盘。
我对该问题的临时解决方案如下所示:拥有 NSOperationQueue 的对象注册 UIApplicationWillTerminateNotification
通知。收到后发送-cancelAllOperations
到队列,它将所有正在运行的操作标记为已取消。
在这一点上,我被困住了。现在我的 NSOperations 被标记为已取消,但它们仍然必须完成当前的内部运行循环并停止。
我的下一个想法是 强制主线程等待,直到所有操作完成 , 然后让 -applicationWillTerminate:
返回。
我希望就如何实现安全交易以防止在后台导入时使应用程序处于损坏状态提供一些专业建议。
最佳答案
您能否以一种即使不是原子的方式至少可以重新启动的方式执行您的导入操作?例如。可重新启动的文件移动可能如下所示:
搜索并删除目标文件夹中的所有文件“*.tmp”。
在需要复制的源文件夹中找到一个文件 - 找到一个“data.DB”
将文件作为“data.DB.tmp”复制到目标文件夹
将“data.DB.tmp”重命名为“data.DB”
在应用程序启动时,搜索并删除所有文件 '*.tmp'
再加上基于事务的“核心数据”数据库更新(即可以回滚),这种方法可以解决您的问题吗?
Rgds,
马丁
关于iphone - 如何以安全的方式在后台线程中执行文件导入?如何在后台进行安全的文件 I/O 事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6226521/