核心数据访问器 - 删除前

Posted

技术标签:

【中文标题】核心数据访问器 - 删除前【英文标题】:Core Data Accessor - Before Delete 【发布时间】:2012-06-08 06:19:32 【问题描述】:

我拥有的是一个名为“MyDocument”的核心数据实体,它具有这些属性

文件名 文件扩展名 文件网址

我从服务器下载了一堆文件,将它们保存在磁盘上的“缓存”文件夹中,然后在数据库中为每个文档插入行。这只是让管理应用程序中的文档变得更容易,而无需列出目录内容等......

一切似乎都很好,除了当我删除实体时,我还想删除磁盘上的关联文件。我可以轻松地做这样的事情

for(MyDocument *myDocument in ParentEntity.mydocuments) 

    [[NSFileManager defaultManager] removeItemAtURL:[NSURL fileURLWithPath:myDocument.fileURL] error:nil];
    [context deleteObject:myDocument];

但我正在尝试通过访问器完成此操作....这样我就可以从任何地方调用 - deleteObject:myDocument 并确保相关文件也会被删除。

我知道我可以使用 Core Data 的外部文件存储选项而完全不用担心这个,但我正在使用 QLPreviewController 来预览这些文档,并且 QLPreviewController 需要一个文件 URL 才能预览该项目。如果我将文档保存在 Core Data 中,每次 Preview 需要它时,我都必须将文件从存储的 NSData 写入磁盘。这没有意义,所以我决定自己将它们存储在外部并在 DB 中保留参考。

那么,我将如何编写一个自定义访问器,它会在对象即将被删除之前跳转并删除关联文件,然后继续删除实际的实体..

提前致谢

【问题讨论】:

【参考方案1】:

NSManagedObject -prepareForDeletion 肯定是您需要在实体中实现的,以处理相关资源。

Core Data 在删除规则传播之前为每个已删除的实体调用 prepareForDeletion。这是实现比 Core Data 提供的非常基本规则更复杂的任何东西的正确位置。

它可以在不向 NSManagedObjectContext 添加东西的情况下工作,它将与默认的 NSManagedObjectContext -deleteObject 一起工作,并且不会与 NSUndoManager 混淆。当然,您必须为您的实体使用自定义类。

【讨论】:

【参考方案2】:

我认为最简洁的方法是简单地将自定义方法添加到您的 NSManagedObject 子类中。下面我将其设为NSManagedObjectContext 的类别,但您也可以将其作为MyDocument 实例方法进行。通过这种方式,您可以显式删除实体和关联文档,同时仍然可以选择仅删除实体。此外,当您不再熟悉您的代码时,您将避免将来意外删除内容;-)。

@interface NSManagedObjectContext (customDelete)
-(void)deleteMyDocumentObjectAndAssociatedFiles:(MyDocument *)object;
@end

@implementation NSManagedObjectContext (customDelete)
-(void)deleteMyDocumentObjectAndAssociatedFiles:(MyDocument *)object 
   [[NSFileManager defaultManager] removeItemAtURL:
     [NSURL fileURLWithPath:object.fileURL] error:nil];
   [self deleteObject:object];

@end

或者作为MyDocument方法(不知道这个“自删除”是否有效):

-(void)deleteSelfAndAssociatedFiles 
   [[NSFileManager defaultManager] removeItemAtURL:
     [NSURL fileURLWithPath:self.fileURL] error:nil];
   [self.managedObjectContext deleteObject:self];

【讨论】:

我可以覆盖 deleteObject 并删除其中的文件吗?

以上是关于核心数据访问器 - 删除前的主要内容,如果未能解决你的问题,请参考以下文章

核心数据原始访问器

核心数据 - 原始设置器/获取器更快吗?啥时候不使用?

核心数据:我应该为每个实体编写一个数据访问对象/管理器/控制器吗?

执行删除规则时未调用自定义对多关系访问器方法

自定义核心数据访问器——setValue:forKey: vs. setPrimitiveValue:forKey:

js创建对象的最佳方式