查看Apple文档,我看到他们建议从AppDelegate中删除Core Data初始化代码。他们的方法如下。
我不明白以下内容
通过使用完成块初始化单独的控制器对象,您已将Core Data堆栈移出应用程序委托,但仍然允许回调应用程序委托,以便用户界面可以知道何时开始请求数据。
文档中的AppDelegate代码
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setDataController:[[DataController alloc] init];
// Basic User Interface initialization
return YES;
}
文档中的DataController代码
@interface MyDataController : NSObject
@property (strong) NSManagedObjectContext *managedObjectContext;
-(void)initializeCoreData;
@end
@implementation MyDataController
-(id)init {
self = [super init];
if (!self) return nil;
[self initializeCoreData];
return self;
}
- (void)initializeCoreData {
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSAssert(mom != nil, @"Error initializing Managed Object Model");
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
[self setManagedObjectContext:moc];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsURL URLByAppendingPathComponent:@"DataModel.sqlite"];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
NSError *error = nil;
NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);
});
}
答案 0 :(得分:1)
1)
In the Core Data programming guide you're looking at,作者正在从App Delegate中取出Core Data(它往往会混淆许多额外的代码,开发人员应该将这些代码拆分成单独的对象)。
其余文档解释说:
建议在自己的内核中创建Core Data堆栈 顶级控制器对象和应用程序委托 初始化该控制器对象并保持对它的引用。这个 行动将促进其内部核心数据代码的整合 拥有自己的控制器,并保持应用程序委托相对干净。
此外:
将持久性存储(
NSPersistentStore
)添加到 持久性商店协调员(NSPersistentStoreCoordinator
)到a 背景队列。这个动作可能需要一段时间,而且 在主队列上执行它可能会阻止用户界面 导致应用程序终止。将持久性存储添加到持久性存储中 协调器,然后您可以回调主队列并请求 用户界面完成并显示给用户
所以是的,在第一个视图控制器显示时,CoreData可能不一定完全正常,但是如果你有一个观察者从该后台队列中寻找NSNotification
,你可以告诉你的UI何时是CoreData准备好依赖。
2)
[DataController init]
在DataController
返回之前不会返回initializeCoreData
对象,因此在didFinishLaunchingWithOptions
返回之后您的UI才会显示,并且您应该已经拥有{ {1}}对象。
答案 1 :(得分:0)
方法YES
的返回applicationDidFinishLaunchingWithOptions
是关键。
核心数据堆栈的初始化在方法返回之前或者在任何视图控制器初始化之前发生。
一旦应用程序被通知它确实正在启动,核心数据堆栈就会被初始化。仅在整个初始化过程之后,该方法返回YES
。之后故事板与其初始控制器一起加载,然后初始控制器的viewDidLoad
被加载。
所以在某种程度上,在初始控制器甚至在屏幕之前很长一段时间,核心数据堆栈都已加载。
希望这可以帮助你理解。