我正在尝试创建基于Core Data的Mac OS X应用程序。我在iOS上使用过Core Data,但与AppKit有些不同。我也在10.7上使用Xcode 4.1,我知道Lion上的一些核心数据已经发生了变化。来自Apple的唯一最新参考是最近的WWDC会议,该会议承诺/建议在Apple.com上更新参考,但大多数核心数据的内容都非常过时。
首先,我使用Xcode使用Core Data生成基于文档的项目。我掏空了一些主菜单位(删除了一些菜单项)并删除了NSWindow
内的Main Menu.xib
对象,创建了我自己的MyDocument.xib
NSWindow
(和子视图)。
问题:
我认为永久存储控制器总是需要一个持久存储,所以如果创建一个新文档,我只是添加一个内存存储。从磁盘打开时,我使用SQLite存储创建它。这是对的吗?
如果writeToURL:ofType:error:
不同,我(表面上)在url
进行商店迁移。但是如果我在writeToURL:ofType:error:
中设置断点,然后点击保存,我的断点就不会被击中。为什么不呢?
如果我选择“还原为已保存”,应用程序会崩溃 - 很难。我必须强制退出它(并退出Xcode)。为什么呢?
(非常)旧的视频教程提出了一种方法,可以轻松地将数据绑定到UIView
,就像表格一样。跟随Xcode是不可能的,因为这么多已经改变了。有没有更新的参考资料?
代码:
MyDocument.h
:
#import <Cocoa/Cocoa.h>
@interface MyDocument : NSPersistentDocument
{
@private
NSManagedObjectModel* mom;
NSPersistentStoreCoordinator* psc;
NSManagedObjectContext* moc;
}
@end
MyDocument.m
:
#import "MyDocument.h"
@interface MyDocument ()
- (void)setUpManagedObjectModel;
- (void)setUpPersistentStoreCoordinator;
- (void)setUpManagedObjectContext;
- (BOOL)addPersistentStore:(NSString*)type url:(NSURL*)url error:(NSError**)outError;
@end
@implementation MyDocument
- (void)dealloc
{
[moc release];
[psc release];
[mom release];
[super dealloc];
}
- (id)init
{
self = [super init];
if (self)
{
[self setUpManagedObjectModel];
[self setUpPersistentStoreCoordinator];
[self setUpManagedObjectContext];
}
return self;
}
- (id)initWithType:(NSString *)typeName error:(NSError **)outError
{
self = [super initWithType:typeName error:outError];
if (self)
{
[self addPersistentStore:NSInMemoryStoreType url:nil error:outError];
}
return self;
}
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError
{
return [self addPersistentStore:NSSQLiteStoreType url:url error:outError];
}
- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError
{
NSPersistentStore* currentStore = [[psc persistentStores] lastObject];
if (![[currentStore URL] isEqual:url])
{
NSPersistentStore* newStore = [psc migratePersistentStore:currentStore
toURL:url
options:nil
withType:typeName
error:outError];
if (!newStore)
{
return NO;
}
}
return [moc save:outError];
}
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"MyDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
// Add any code here that needs to be executed once the windowController has loaded the document's window.
}
+ (BOOL)autosavesInPlace
{
return YES;
}
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
NSLog(@"menu item: %@", [item title]);
return YES;
}
#pragma mark Private Methods
- (void)setUpManagedObjectModel
{
NSURL* modelUrl = [[NSBundle mainBundle] URLForResource:@"MyDatabase" withExtension:@"momd"];
mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
}
- (void)setUpPersistentStoreCoordinator
{
psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
}
- (void)setUpManagedObjectContext
{
moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:psc];
}
- (BOOL)addPersistentStore:(NSString*)type url:(NSURL*)url error:(NSError**)outError
{
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSPersistentStore* ps = [psc addPersistentStoreWithType:type
configuration:nil
URL:url
options:options
error:outError];
return (ps != nil);
}
@end
答案 0 :(得分:2)
如果您使用NSPersistentDocument
,默认情况下所有这些都是为您处理的,您无需进行任何核心数据设置。 NSPersistentDocument
将自动处理创建,保存和迁移持久性存储。
如果要控制持久性存储的配置方式,只需覆盖
即可-configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:
然后,您可以在需要时向文档询问managedObjectContext
并编写代码。
我强烈建议您阅读Apple的NSPersistentDocument
tutorial以获取更多详细信息。