7c9*_*fdf 5 iphone sdk core-data objective-c ios
我对在哪里设置我的核心数据堆栈感到有点困惑.在Appdelegate中或使用UIManagedDocument的共享实例,在这里描述?:http://adevelopingstory.com/blog/2012/03/core-data-with-a-single-shared-uimanageddocument.html
现在我通过我的AppDelegate中的核心数据堆栈设置,我在视图控制器之间传递我的MOC.但是,迁移到UIManagedDocument并创建共享实例会更好吗,所以我不必一直通过MOC?还因为它更新?
UIManagedDocument用于将数据(通常是文件)同步到iCloud.它仅与核心数据相关.
核心数据设置通常是在AppDelegate这里进行的,因此你在那里做的事情没有任何问题.事实上,如果您使用Core Data创建一个新项目,那么Xcode模板将如何实现.
您通常不需要将ManagedObjectContext视图控制器传递给viewcontroller.最好创建一个单例数据访问层,它可以在应用程序的任何位置提供上下文.在某些情况下,您可能希望为viewcontroller提供私有MOC,但不常见.
这是创建单例DataAccessLayer的一些代码:
DataAccessLayer.h
@interface DataAccessLayer : NSObject
//Saves the Data Model onto the DB
- (void)saveContext;
//DataAccessLayer singleton instance shared across application
+ (id) sharedInstance;
+ (void)disposeInstance;
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound
// to the persistent store coordinator for the application.
+ (NSManagedObjectContext *)context;
@end
Run Code Online (Sandbox Code Playgroud)
DataAccessLayer.m
#import "DataAccessLayer.h"
//static instance for singleton implementation
static DataAccessLayer __strong *manager = nil;
//Private instance methods/properties
@interface DataAccessLayer ()
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and
// bound to the persistent store coordinator for the application.
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's
// store added to it.
@property (readonly,strong,nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory;
@end
@implementation DataAccessLayer
@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
//DataAccessLayer singleton instance shared across application
+ (id)sharedInstance
{
@synchronized(self)
{
if (manager == nil)
manager = [[self alloc] init];
}
return manager;
}
+ (void)disposeInstance
{
@synchronized(self)
{
manager = nil;
}
}
+(NSManagedObjectContext *)context
{
return [[DataAccessLayer sharedInstance] managedObjectContext];
}
//Saves the Data Model onto the DB
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
//Need to come up with a better error management here.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and
// bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
return __managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the
// application's model.
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil)
return __managedObjectModel;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model"
withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the
// application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
return __persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"MyData.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
}
@end
Run Code Online (Sandbox Code Playgroud)
只要您需要上下文,就可以使用以下方法获取它:
NSManagedObjectContext *context = [DataAccessLayer context];
Run Code Online (Sandbox Code Playgroud)
这种设计通常很有效.NSManagedObjectContext是一个非常轻量级的对象,因此没有真正的性能损失来保持它.但是,如果您需要在其他线程上执行Core Data,则设计需要稍微改变一下.来自Apple的文档:
您必须在将使用它的线程上创建托管上下文.如果使用NSOperation,请注意在与调用者相同的线程上调用其init方法.因此,您不能在队列的init方法中为队列创建托管对象上下文,否则它将与调用方的线程相关联.相反,您应该在main(用于串行队列)或start(用于并发队列)中创建上下文.
使用线程限制,不应在线程之间传递托管对象或托管对象上下文.要跨越线程边界从另一个上下文"传递"托管对象,您可以:
- 传递其对象ID(objectID)并在接收的托管对象上下文中使用objectWithID:或existingObjectWithID:error :. 必须保存相应的托管对象 - 您无法将新插入的托管对象的ID传递给另一个上下文.
- 在接收上下文上执行提取.
| 归档时间: |
|
| 查看次数: |
3834 次 |
| 最近记录: |