在哪里放置“核心数据堆栈”在Cocoa / Cocoa Touch应用程序中
在iPhone核心数据模板中,苹果将核心数据堆栈放置在应用程序委托中。
然而,我最初的意图是将这些代码移入自己的类,其职责是处理核心数据栈的pipe理。
你通常把这个function封装在自己的类中,还是把它放在App Delegate中?
总结:不需要创build一个单例来pipe理核心数据堆栈; 确实这样做可能会产生相反的效果。
核心数据堆栈正好由应用程序委托创build。 但是,重要的是,正如所有例子所示,堆栈(主要是托pipe对象上下文) 不会直接从堆栈(*)中检索。 相反,上下文被传递给第一个视图控制器,并且从上下文或被pipe理对象中的上下文被从一个视图控制器传递到下一个(如访问核心数据栈中所述 )。 这遵循iPhone所有应用程序的基本模式:将数据或模型控制器从一个视图控制器传递到下一个。
这里描述的单例的典型作用是作为模型控制器。 使用核心数据,托pipe对象上下文已经是模型控制器。 它还使您能够访问堆栈的其他部分,如果需要的话。 而且,在某些情况下(如文档中所述),您可能需要使用不同的上下文来执行一组离散的操作。 因此,视图控制器的适当货币单位通常是托pipe对象上下文,否则是托pipe对象。 使用和传递pipe理一个堆栈(从中获取上下文)的单例对象通常最多引入了一个不必要的间接级别,最坏的情况是引入了不必要的应用程序僵化。
(*)没有示例使用以下方法检索上下文:
[[UIApplication delegate] managedObjectContext];
我有一个单独的课,让我做我的核心数据pipe理,我不把它留在应用程序的代表。 我宁愿不使用我可能需要的方法来获取应用程序委托类,例如获取某些对象等
由于以下原因,我在App委托中保留了核心数据逻辑:
1)在其他类中移动代码没有任何实际优势:代理的概念完全由App代理处理的核心数据逻辑实现,因为核心数据模型实际上是应用程序的基本部分;
2)在我看到的所有示例代码(包括苹果示例)中,核心数据内容都由App代理处理;
3)即使在核心数据书中,通常的做法是让应用程序委托处理与核心数据相关的代码;
4)就个人而言,我不认为通过专门的核心数据类来改善可读性或其他任何事情,但这是一个个人品味的问题,我不会在这里讨论什么方法是最好的。 对我来说,保持function的简单性很重要。
在我的情况下,我会问自己的问题是“核心数据栈是属于谁”? 数据本身真的是应用程序的省,不是吗? (Mac上的CF核心数据,在这里你可能有一个应用程序能够同时处理多个文档,所以核心数据堆栈属于每个文档。)
在任何Cocoa / Cocoa Touch应用程序中,App Delegate通常是自定义应用程序行为的首选方式,因此这是Core Data堆栈的自然之处。
现在,我怀疑你遇到的问题是,不断地写下这样的东西感觉不对:
NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
我通常在这些情况下做的是写function(不是这样的):
NSManagedObjectContext *UIAppManagedObjectContext() { return [*(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; }
我为NSPersistentStoreCoordinator
和NSManagedObjectModel
写了一个类似的函数。 我将所有这些都放在App Delegate的.h / .m文件中,因为它们也是应用程序级别的对象。
我将在一个新的答案中列出这个。 (我已经放弃了我之前的FJSCoreDataStack类来支持这个)
我处理这个新的方法是在NSManagedObjectContext上使用一个类别。 我添加了以下的类方法:
+ (NSManagedObjectContext *)defaultManagedObjectContext; + (NSManagedObjectContext *)scratchpadManagedObjectContext; + (NSManagedObjectModel *)managedObjectModel; + (NSPersistentStoreCoordinator *)persistentStoreCoordinator; + (NSString *)applicationDocumentsDirectory;
这使得我的应用程序委托中的所有内容都保留了下来,并且我应该select使用它来提供单例访问。 不过,我仍然使用App Delegate的dependency injection(就像mmalc所说的那样,它在我的代码中引入了灵活性)。 我只是将所有“核心数据堆栈”代码移入NSManagedObjectCOntext类别。
我喜欢通过参考,特别是因为我有一个很好的“便签本上下文”的方法。 这使我的视图控制器更加灵活,因为我没有将它们提交给“defaultManagedObjectContext”。
也与iPhone世界中的对话相关(可能与您的体系结构有关): NSFetchedResultsController和构造NSFetchRequests
我赞成让应用程序委托人知道模型的起始位置,并让模型知道受pipe对象上下文在哪里。 模型的核心数据“模型”看起来像是模型的一个实现细节,控制器类(如应用程序委托)应该问“给我关于模型的这些信息”,模型应该知道如何回答那个问题。 因此,通过控制器对象提供一个核心数据对象看起来像是一个漏洞的抽象。