【问题标题】:Using iCloud enabled Core Data NSArray-taking method使用启用了 iCloud 的 Core Data NSArray-taking 方法
【发布时间】:2015-04-04 18:17:09
【问题描述】:

我一直在我的应用程序中设置和测试 Core Data,一切都在本地运行良好;但是,只要我通过以下方式启用 iCloud:

NSDictionary *options;
    if ([self iCloudEnabled]) {
        options = @{NSSQLitePragmasOption: @{@"journal_mode" : @"DELETE"},
                    NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore"};
        [self subscribeToNotifications];
    } else
        options = @{NSSQLitePragmasOption: @{@"journal_mode" : @"DELETE"}};

然后运行我的应用程序,我在控制台中收到以下垃圾邮件错误:

*** ERROR: this process has called an NSArray-taking method, such as initWithArray:, and passed in an NSSet object.  This is being worked-around for now, but will soon cause you grief.

打印完该错误后,一切似乎都正常工作。

我能找到的唯一其他相关问题是here 和here,它们都没有帮助。

我什至找不到任何地方说明该错误的含义。

感谢任何帮助。

编辑:根据我的发现,它发生在我的 managedObjectContext 初始化之后并且在“使用本地存储:0”打印到控制台之前。问题是,我不知道当时正在执行什么(因为我没有调用任何东西);它似乎在后台线程中。

EDIT2:我还应该提到,这只发生在第一次启动应用程序时(在 iCloud“一次性”设置上)。

EDIT3:这是初始化我的上下文的代码:

- (NSURL *)coreDataLocalURL {
    // The directory the application uses to store the Core Data store file.
    NSURL *result = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

    result = [result URLByAppendingPathComponent:@"TheAnglersLog"];

    NSError *e;
    if (![[NSFileManager defaultManager] fileExistsAtPath:result.path])
        // create TheAnglersLog directory if it doesn't exist
        [[NSFileManager defaultManager] createDirectoryAtPath:result.path
                                  withIntermediateDirectories:NO
                                                   attributes:nil
                                                        error:&e];

    return result;
}

- (NSManagedObjectModel *)managedObjectModel {
    // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
    if (_managedObjectModel != nil)
        return _managedObjectModel;

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TheAnglersLog" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    // Create the coordinator and store

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self coreDataLocalURL] URLByAppendingPathComponent:@"TheAnglersLog.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";

    NSDictionary *options;
    if ([self iCloudEnabled]) {
        options = @{NSSQLitePragmasOption: @{@"journal_mode" : @"DELETE"},
                    NSPersistentStoreUbiquitousContentNameKey : @"TheAnglersLogCloudStore"};
        [self subscribeToNotifications];
    } else
        options = @{NSSQLitePragmasOption: @{@"journal_mode" : @"DELETE"}};

    NSLog(@"Is iCloud enabled? %@", [self iCloudEnabled] ? @"YES" : @"NO");

    NSPersistentStore *store;

    if (!(store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])) {
        // Report any errors we got.
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];

        NSLog(@"Error in persistentStoreCoordinator: %@, %@", error, [error userInfo]);
    }

    NSLog(@"Core Data URL: %@", [store URL]);

    return _persistentStoreCoordinator;
}

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

【问题讨论】:

  • 我的程序中也收到了同样的不祥警告。我将 iCloud 与我的核心数据一起使用。我的托管对象子类与另一个实体具有一对多的关系,并将其声明为 NSOrderedSet。当推送无处不在的更改时,我会收到该警告。如果我可以在不关闭 iCloud 的情况下让它消失,我会发布答案。

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


【解决方案1】:

它准确地告诉您问题所在:某处(不是在您发布的代码中),您将NSSet 传递给期望NSArray 的东西。 NSArray 是有序且包含重复的,NSSet 是无序且不包含重复的。它为您将其转换为一组,因此它不会崩溃,但抱怨它将来可能不会继续这样做。

【讨论】:

  • 我也是这么想的,但是什么都找不到。不过我会再看一遍。另外,为什么只有在我初始化持久存储时启用了 iCloud 时才会出现这种情况?
  • 我根本没有修改任何数据。这发生在应用程序启动时。通常我会加载保存的数据,但此时没有保存的数据。这发生在我初始化我的 managedObjectContext 之后。
  • 初始化上下文的代码是什么样的?
  • 在第一篇文章中添加了它,但它基本上是Xcode提供的默认核心数据堆栈。在 addPersistentStore 选项中删除 NSPersistentStoreUbiquitousContentNameKey 可以解决问题,但不允许我使用 iCloud。
  • 我遇到了同样的问题。我注意到错误是在 iCloud 无处不在的容器更新期间发送的。
猜你喜欢
  • 2015-07-08
  • 2015-04-09
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 2011-12-07
  • 2013-11-23
  • 1970-01-01
相关资源
最近更新 更多