使用启用 iCloud 的核心数据 NSArray 获取方法
Using iCloud enabled Core Data NSArray-taking method
我一直在我的应用程序中设置和测试核心数据,一切都在本地运行良好;但是,只要我通过以下方式启用 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 and here,但它们都没有帮助。
我什至找不到任何地方说明该错误的含义。
感谢任何帮助。
编辑:根据我的发现,它发生在我的 managedObjectContext 初始化之后和 "Using local storage: 0" 打印到控制台之前。问题是,我不知道那个时候正在执行什么(因为我没有调用任何东西);它似乎在后台线程中。
EDIT2:我还应该提到,这只会在应用程序首次启动时发生(在 iCloud "one-time" 设置上)。
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;
}
它准确地告诉您问题所在:在某个地方(不是在您发布的代码中),您将 NSSet
传递给需要 NSArray
的对象。 NSArray
是有序的且包含重复项,NSSet
是无序的且不包含重复项。它为您将它转换为一组,因此它不会崩溃,但抱怨它可能不会在未来继续这样做。
我一直在我的应用程序中设置和测试核心数据,一切都在本地运行良好;但是,只要我通过以下方式启用 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 and here,但它们都没有帮助。
我什至找不到任何地方说明该错误的含义。
感谢任何帮助。
编辑:根据我的发现,它发生在我的 managedObjectContext 初始化之后和 "Using local storage: 0" 打印到控制台之前。问题是,我不知道那个时候正在执行什么(因为我没有调用任何东西);它似乎在后台线程中。
EDIT2:我还应该提到,这只会在应用程序首次启动时发生(在 iCloud "one-time" 设置上)。
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;
}
它准确地告诉您问题所在:在某个地方(不是在您发布的代码中),您将 NSSet
传递给需要 NSArray
的对象。 NSArray
是有序的且包含重复项,NSSet
是无序的且不包含重复项。它为您将它转换为一组,因此它不会崩溃,但抱怨它可能不会在未来继续这样做。