如何正确删除“临时”文件应用程序退出时的 NSManagedObject
我创建一个临时 NSManagedObject 并将其与主 NSManagedObjectContext 关联。我需要能够将其视为上下文中功能齐全的对象(执行获取请求等),因此无法在没有关联上下文的情况下创建它。我在 ViewWillDisappear 中添加了删除托管对象的逻辑,条件是新的视图控制器不仅仅被推入堆栈:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
} else {
// View is disappearing for some other reason
[self.community.managedObjectContext deleteObject:self.community];
}
}
这似乎在除应用程序退出之外的所有情况下都正确删除了托管对象。我尝试删除 viewDidUnload 中的对象,但似乎在应用程序退出时不会调用该方法。我考虑过创建第二个托管对象上下文,但希望尽可能避免主要开销。
谢谢, 格雷厄姆
I create a temporary NSManagedObject and associate it with the main NSManagedObjectContext. I need be able to treat it as a fully functioning object (perform fetch requests, etc) inside the context and thus cannot create it without an associated context. I include logic to delete the managed object in ViewWillDisappear under the condition that a new view controller was not just pushed onto the stack:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
} else {
// View is disappearing for some other reason
[self.community.managedObjectContext deleteObject:self.community];
}
}
This seems to properly delete the managed object in all cases except for the application quitting. I tried deleting the object in viewDidUnload but it seems the method is not called upon the application quitting. I have considered creating a second managed object context, but want to avoid the major overhead if possible.
Thanks,
Graham
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我知道您已经有了一个可行的答案,但如果您的对象确实是临时的,并且永远不会被保存,为什么不在子上下文中创建它呢?它仍然具有您想要的所有获取可见性,但永远不会被推送到其他上下文,也不会保存在物理数据库中,直到您在上下文上调用 save 。
如果你从不调用 save,临时对象将永远不会被保存,从而真正使其成为临时对象。
更重要的是......您根本不必编写任何额外的代码或处理所有“退出”条件,因为它从未被放入实际的数据库中。
I understand you already have a working answer, but if your object is truly temporary, and will never be saved, why not just create it in a child context? It will still have all the fetch visibility you desire, but will never get pushed to the other contexts, nor saved in the physical database until you call save on the context.
If you never call save, the temporary object will never be saved, thus truly making it temporary.
And the kicker... you don't have to write any extra code at all or handle all the "exiting" conditions since it never got put into the actual database.
applicationWillTerminate
及其多任务表兄弟可以工作,但由于您只删除单个对象,因此最好的方法是在每次删除后保存上下文。只需调用
- (BOOL)save:(NSError **)error
:applicationWillTerminate
and its multi-tasking cousins work, but since you are only deleting a single object the best way is to save your context after every delete.Just call
- (BOOL)save:(NSError **)error
:将托管对象作为类变量保留在共享实例中,以便可以从应用程序中的更多位置访问它,而不是处理它的类。
有两种场景:
1)iOS 4.0之前
当 applicationWillTerminate 时,您可以从上下文中删除该对象。
2) 自 iOS 4.0 起。
当您的应用程序进入后台并且您将终止该进程(使用“终止应用程序栏”的困难方式)时, applicationWillTerminate 将永远不会被调用。您无法识别此事件。所以你被 applicationWillTerminate 搞砸了。
你必须像这样解决它:
- applicationWillEnterBackground:->将标识符保存到用户默认值或简单文件中的托管对象。
- applicationDidFinishLaunching:->如果文件存在,则删除它所引用的托管对象。
- applcationWillEnterForeground:->删除该文件。
现在,当您的应用程序进入后台并返回时,您将具有相同的状态,并且该对象不会被删除。
当您终止应用程序时,该对象将在启动时被删除。
Keep the managed object in a shared instance of as a class variable so it is reachable from more places in your application then the class you handle it from.
There are two scenarios:
1) before iOS 4.0
When the applicationWillTerminate you can delete the object from the context.
2) Since iOS 4.0.
When your application will go in the background and you will kill the process (the hard way, with the 'kill app bar'), the applicationWillTerminate will never get called. You cannot recognize this event. So your screwed with the applicationWillTerminate.
You will have to solve it like this:
- applicationWillEnterBackground: -> save an identifier to the managed object in the userdefaults or a simple file.
- applicationDidFinishLaunching: -> if file exists, delete the managed object it is referring to.
- applcationWillEnterForeground: -> delete the file.
Now when your app goes into background and comes back, you will have the same state and the object will not be deleted.
When you kill your app, the object will be deleted on startup.
在您的应用程序委托中,实现 -applicationWillTerminate: 方法。在从内存中清除应用程序之前调用此方法,您可以在那里删除临时托管对象。
In your app delegate, implement the -applicationWillTerminate: method. This method is called right before your application is purged from memory and you can delete the temporary managed object there.