我编写了一个使用Core Data存储其内容的iOS应用程序。数据存储在托管对象中并在单独的线程中更新(我正在使用GCD)。 Apple在其Core Data Programming Guide
模式中建议采用两种方式来采用Core Data在多线程环境中使用:
所以我选择了第一个。
我有一个Database
类来管理所有与Core Data相关的东西。
// Database.h
#import <CoreData/CoreData.h>
@interface Database : NSObject
@property (nonatomic, retain, readonly) NSManagedObjectModel *model;
@property (nonatomic, retain, readonly) NSManagedObjectContext *context;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *coordinator;
+ (Database *)sharedInstance;
@end
// Database.m
#import "Database.h"
static NSManagedObjectModel *sharedModel;
static NSPersistentStoreCoordinator *sharedCoordinator;
static NSMutableDictionary *contexts;
@implementation Database
+ (NSMutableDictionary *)contextsDictionary
{
if (!contexts) {
contexts = [[NSMutableDictionary alloc] init];
}
return contexts;
}
+ (NSManagedObjectContext *)contextForThread:(NSThread *)thread
{
id threadKey = @(thread.hash);
NSManagedObjectContext *context = [Database contextsDictionary][threadKey];
if (!context) {
context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = sharedCoordinator;
contexts[threadKey] = context;
[context release];
[[NSNotificationCenter defaultCenter] addObserver:[Database class]
selector:@selector(threadWillExit:)
name:NSThreadWillExitNotification
object:thread];
}
return context;
}
+ (void)threadWillExit:(NSThread *)thread
{
id threadKey = @(thread.hash);
[contexts removeObjectForKey:threadKey];
[[NSNotificationCenter defaultCenter] removeObserver:[Database class]
name:NSThreadWillExitNotification
object:thread];
}
+ (Database *)sharedInstance
{
static Database *shared;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[Database alloc] init];
});
return shared;
}
- (id)init
{
self = [super init];
if (self) {
sharedModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
sharedCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:sharedModel];
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *storeUrl = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent: @"MyModelFile"]];
NSError *error = nil;
[sharedCoordinator addPersistentStoreWithType:NSBinaryStoreType
configuration:nil
URL:storeUrl
options:nil
error:&error];
NSAssert(!error, @"Initialization error %@", error);
}
return self;
}
- (NSManagedObjectModel *)model
{
return sharedModel;
}
- (NSPersistentStoreCoordinator *)coordinator
{
return sharedCoordinator;
}
- (NSManagedObjectContext *)context
{
return [Database contextForThread:[NSThread currentThread]];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[sharedModel release];
[sharedCoordinator release];
[contexts release];
[super dealloc];
}
@end
所以我很好奇,我做得对吗?我的代码有问题吗?我可以在这里使用任何模式吗?
感谢。
答案 0 :(得分:0)
所描述的多线程模式现在不相关,因为核心数据具有内置并发支持。如文章Core Data Release Notes for OS X v10.7 and iOS 5.0和Common Background Practices中所述,可以使用NSPrivateQueueConcurrencyType
或NSMainQueueConcurrencyType
配置适当的并发类型的moc。然后,可以在传递给performBlock
或performBlockAndWait
方法的块中执行具有托管对象上下文的每个操作,并让核心数据内部处理所有并发内容。