首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >核心数据初始化

核心数据初始化
EN

Stack Overflow用户
提问于 2016-09-18 16:47:20
回答 2查看 1.2K关注 0票数 2

看一下苹果的文档,我发现他们建议将核心数据初始化代码从AppDelegate中删除。他们的做法如下。

我不明白的是以下几点

  1. 文件中的下面一句。如何对应用程序委托进行回调?我在下面的代码片段中没有看到一个。他们想让我们补充一下。

通过使用完成块初始化单独的控制器对象,您已经将核心数据堆栈从应用程序委托中移出,但是您的仍然允许对应用程序委托进行回调,以便用户界面能够知道何时开始请求数据。

  1. AppDelegate调用init of DataController,这反过来调用initializeCoreData。但是initializeCoreData在后台线程中设置持久存储协调器。这意味着,如果我们转换到应用程序的第一个视图,并且它的视图控制器从核心数据请求数据,那么事情还没有建立起来。这不是个问题吗?这是否意味着他们希望我们显示一个不同的启动屏幕&为回调注册,该回调告诉我们,CoreData初始化是在迁移到实际的第一应用程序视图之前完成的。

文档中的AppDelegate代码

代码语言:javascript
复制
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [self setDataController:[[DataController alloc] init];
    // Basic User Interface initialization
    return YES;
}

文档中的DataController代码

代码语言:javascript
复制
@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]);
    });
}
EN

回答 2

Stack Overflow用户

发布于 2016-09-18 16:59:54

1)

在核心数据编程指南中,您将看到,作者正在将核心数据从App中提取出来(它往往会被大量额外的代码弄得乱七八糟,开发人员确实应该将这些代码分割成单独的对象)。

文件的其余部分解释:

建议在它自己的顶级控制器对象中创建Core数据堆栈,并且应用程序委托初始化该控制器对象并保存对它的引用。此操作将促进核心数据代码在其自己的控制器中的合并,并保持应用程序委托相对干净。

另外:

将持久化存储(NSPersistentStore)添加到持久存储协调器(NSPersistentStoreCoordinator)到后台队列。该操作可能会花费未知的时间,在主队列上执行该操作会阻塞用户界面,可能导致应用程序终止。 一旦将持久存储添加到持久存储协调器中,您就可以调用主队列并请求完成用户界面并将其显示给用户。

因此,在显示第一个视图控制器时,CoreData可能不一定完全打开,但是如果您有一个观察者从该后台队列中查找NSNotification,则可以告诉您的UI何时可以依赖CoreData。

2)

[DataController init][DataController init]返回之前不会返回DataController对象,因此您的UI直到didFinishLaunchingWithOptions返回之后才会显示,并且您应该已经有了一个DataController对象。

票数 1
EN

Stack Overflow用户

发布于 2016-09-18 17:00:15

从方法YES返回applicationDidFinishLaunchingWithOptions是关键。

核心数据堆栈的初始化发生在方法返回之前,或者更确切地说是在初始化任何视图控制器之前。一旦通知应用程序它确实正在启动,核心数据栈就会被初始化。只有在整个初始化过程之后,该方法才返回YES。之后,故事板与其初始控制器一起加载,然后加载初始控制器的viewDidLoad

所以在某种程度上,在初始控制器甚至出现在屏幕上之前的很长一段时间内,核心数据堆栈都会被加载。

希望这能帮你理解。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39560195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档