使用启用iCloud的Core Data NSArray采取方法 [英] Using iCloud enabled Core Data NSArray-taking method

查看:84
本文介绍了使用启用iCloud的Core Data NSArray采取方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在我的应用中设置和测试Core Data,并且在本地一切正常。但是,只要我通过以下方式启用iCloud,就可以:

  NSDictionary *选项; 
if([self iCloudEnabled]){
选项= @ {NSSQLitePragmasOption:@ {@ journal_mode:@ DELETE},
NSPersistentStoreUbiquitousContentNameKey:@ iCloudStore};
[self SubscribeToNotifications];
} else
选项= @ {NSSQLitePragmasOption:@ {@ journal_mode:@ DELETE}};

并运行我的应用程序,在控制台中出现以下错误:

  ***错误:此进程调用了NSArray采用方法,例如initWithArray :,并传入了NSSet对象。目前正在解决此问题,但很快会引起您的悲伤。 

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



我能找到的唯一其他相关问题是这里 。 = j&q; q =& esrc = s& source = web& cd = 2& cad = rja& uact = 8& ved = 0CCUQFjAB& url = http%3A%2F%2Fstackoverflow.com%2Fquestions%2F25528019%2Fcore-data -relation-between-objects& ei = -8XSVOXgE6nbsASdi4DoDg& usg = AFQjCNE_unN7JH0jVJcoq7CSm1bFLA-PaQ& sig2 = GYXrEr5vj1-qW2nkBJRHkQ $ ,都不是有用的, b

我什至找不到



感谢任何帮助。



编辑:根据我的经验发现它是在初始化ManagedObjectContext之后并且在将使用本地存储:0打印到控制台之前发生的。问题是,我不知道那段时间正在执行什么操作(因为我什么也没打电话);



EDIT2:我还应该提到,这仅在应用程序首次启动时发生(在iCloud上一次性)



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

 -(NSURL *)coreDataLocalURL {
//应用程序用于存储核心数据存储文件的目录。
NSURL * result = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

结果= [结果URLByAppendingPathComponent:@ TheAnglersLog];

NSError * e;
if(![[[NSFileManager defaultManager] fileExistsAtPath:result.path])
//创建TheAnglersLog目录(如果不存在)
[[NSFileManager defaultManager] createDirectoryAtPath:result.path
withIntermediateDirectories:否
属性:nil
错误:& e];

返回结果;
}

-(NSManagedObjectModel *)managedObjectModel {
//应用程序的托管对象模型。对于应用程序来说,找不到并加载其模型是一个致命错误。
if(_managedObjectModel!= nil)
返回_managedObjectModel;

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

return _managedObjectModel;
}

-(NSPersistentStoreCoordinator *)persistentStoreCoordinator {
//应用程序的持久性存储协调器。此实现创建并返回了一个协调器,并已将应用程序商店添加到其中。
if(_persistentStoreCoordinator!= nil){
return _persistentStoreCoordinator;
}

//创建协调器并存储

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[selfmanagedObjectModel]];
NSURL * storeURL = [[self coreDataLocalURL] URLByAppendingPathComponent:@ TheAnglersLog.sqlite]];
NSError *错误=无;
NSString * failureReason = @创建或加载应用程序的已保存数据时出错。;

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

NSLog(@是否启用了iCloud?%@,[self iCloudEnabled]吗?@@ YES:@ NO);

NSPersistentStore * store;

if(!(store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:& error])){
//报告我们得到的任何错误。
NSMutableDictionary * dict = [NSMutableDictionary字典];
dict [NSLocalizedDescriptionKey] = @无法初始化应用程序的已保存数据;
dict [NSLocalizedFailureReasonErrorKey] = failureReason;
dict [NSUnderlyingErrorKey] =错误;
错误= [NSError errorWithDomain:@ YOUR_ERROR_DOMAIN代码:9999 userInfo:dict];

NSLog(@ persistentStoreCoordinator中的错误:%@,%@,错误,[错误userInfo]);
}

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

return _persistentStoreCoordinator;
}

-(NSManagedObjectContext *)managedObjectContext {
//返回应用程序的托管对象上下文(已绑定到该应用程序的持久存储协调器。)
if(_managedObjectContext!= nil){
返回_managedObjectContext;
}

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


解决方案

这正是在告诉您问题所在:在某个地方(不在您发布的代码中),您正在将 NSSet 传递给需要 NSArray 的对象。 NSArray 是有序的并且包含重复项, NSSet 是无序的并且不包含重复项。它为您将其转换为一个集合,这样它就不会崩溃,但抱怨它将来可能不会继续这样做。


I've been setting up and testing Core Data in my app and everything works great locally; however, as soon as I enable iCloud via:

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

And run my app, I get the following error spammed in the console:

*** 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.

When that error is done printing, everything seems to work normally.

The only other related questions I could find were here and here, and neither of them were helpful.

I can't even find anywhere that says what that error means.

Any help is appreciated.

EDIT: From what I've found it's happening after my managedObjectContext is initialized and before the "Using local storage: 0" is printed to the console. Problem is, I have no idea what's being executed in that time (because I'm not calling anything); it seems to be in a background thread.

EDIT2: I should also mention that this only happens the first time the app is launched (on the iCloud "one-time" setup).

EDIT3: Here's the code that initializes my context:

- (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;
}

解决方案

It's telling you precisely the problem: Somewhere (not in the code you posted), you're passing an NSSet to something which expects an NSArray. NSArray is ordered and duplicate-inclusive, NSSet is unordered and duplicate-exclusive. It converted it to a set for you so it wouldn't crash, but is complaining it may not continue to do so in the future.

这篇关于使用启用iCloud的Core Data NSArray采取方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆