【问题标题】:App stalls on addPersistentStoreWithType with iCloud应用程序在 iCloud 的 addPersistentStoreWithType 上停止
【发布时间】:2013-01-23 13:11:38
【问题描述】:

我的 persistentStoreCoordinator 中有以下代码。没有 iCloud 部分,它工作正常。对于 iCloud,它在 addPersistentStoreWithType 方法上停止。没有错误,它只是停止并不会继续。

有什么想法吗?

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [NSURL fileURLWithPath:STORE_PATH];

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSMutableDictionary *options = [NSMutableDictionary dictionary];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];


        NSFileManager *fileManager = [NSFileManager defaultManager];

        NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
        NSLog(@"icloud: %@", iCloud);

        if (iCloud) {

            NSString *iCloudLogsDirectoryName = @"Logs";
            NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];

            //Create logs directory, in case it doesn't exist
            if([fileManager fileExistsAtPath:[iCloudLogsPath path]] == NO) {
                NSLog(@"logs directory doesn't exist");
                NSError *fileSystemError;
                [fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]
                       withIntermediateDirectories:YES
                                        attributes:nil
                                             error:&fileSystemError];
                if(fileSystemError != nil) {
                    NSLog(@"Error creating logs directory %@", fileSystemError);
                }
            }

            NSString *iCloudEnabledAppID = @"app id removed from stackoverflow";

            [options setObject:iCloudEnabledAppID            forKey:NSPersistentStoreUbiquitousContentNameKey];
            [options setObject:iCloudLogsPath                forKey:NSPersistentStoreUbiquitousContentURLKey];
            NSLog(@"logs path: %@", iCloudLogsPath);
        }

    [_persistentStoreCoordinator lock];

    NSError *error;

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                   configuration:nil
                                                             URL:storeURL
                                                         options:options
                                                           error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    else {
        NSLog(@"done adding persistent store");
    }

    [_persistentStoreCoordinator unlock];

    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil];
        [self.delegate contextWasSetupInManager:self];
    });

    });

    return _persistentStoreCoordinator;

}

【问题讨论】:

    标签: iphone ios objective-c core-data icloud


    【解决方案1】:

    这在 iCloud 中很常见。 Apple 建议您将其放在后台队列中,因为该调用可能会阻塞。它阻塞是因为 Core Data 实际连接到 iCloud 服务器并开始下载任何可用的新数据。呼叫在完成之前不会继续。如果有大量数据要下载,您可以稍等片刻。

    有时没有明显的原因需要一段时间。像那样片状的。

    最终,您所看到的几乎就是 iCloud 现在的样子。提交一两个错误并希望情况有所改善。

    【讨论】:

    • 我能否允许用户在我的应用程序中继续使用核心数据,并且此方法在后台运行?
    • 很遗憾没有。您可以让此方法运行只要它需要运行,但在它完成之前您没有数据存储。这意味着您无法将任何内容输入或输出 Core Data。我已经看到了一些关于如何处理这个问题的想法,但没有一个是真正成功的。
    • 但这不是那种.. 破坏我的用户体验,iCloud 可以花费尽可能长的时间(分钟、小时)将用户保持在同一点而不让他们使用应用程序除此以外?当然有办法解决这个问题,另一种选择?
    • 是的,这对您的用户体验来说是个问题。至于替代方案,我一直在研究替代方法一段时间,但还没有达到我可以使用 Core Data + iCloud 发布应用程序的地步。您可能需要考虑其他方法 - 或者准备提出自己的创造性方法来让 Core Data + iCloud 不至于糟糕。
    【解决方案2】:

    我刚刚在我的一台测试设备(运行 iOS 6.1 的 iPhone 5)上体验到了这一点。恢复出厂设置,然后从手机的当前备份恢复修复它。

    我不确定这是否是解释,但通过设备设置 > iCloud > 存储和备份删除应用程序的 iCloud 普遍存在容器数据似乎存在问题。这可能会使设备处于普遍存在容器的一些残余物仍然存在且无法移除的状态。在设备上进行完全擦除和恢复似乎可以解决问题。

    我发现了一篇看起来与此问题有关的旧帖子 (http://stackmonthly.com/2011/11/core-data),以及 OpenRadar 上的此条目 (http://openradar.appspot.com/10440734)。我搞砸了几个小时,直到我擦除并恢复了设备,它运行良好:addPersistentStoreWithType 几乎立即完成。

    接下来,我将尝试使用 WWDC 2012 示例应用程序 SharedCoreData(会话 227)中的 nukeAndPave 方法清除存储,而不是从设置中手动删除存储。希望这样可以防止这种情况再次发生。

    【讨论】:

      【解决方案3】:

      我不完全确定为什么会出现这些问题,但通过重置手机设置,我在解决此类问题方面取得了很大成功:

      设置>常规>重置>重置所有设置

      【讨论】:

        猜你喜欢
        • 2017-02-27
        • 2012-11-29
        • 2011-12-26
        • 1970-01-01
        • 2017-12-11
        • 1970-01-01
        • 2015-03-18
        • 2023-03-10
        • 1970-01-01
        相关资源
        最近更新 更多