Я пытаюсь создать приложение Mac OS X на базе Core Data. Я использовал Core Data на iOS, но с AppKit все немного по-другому. Я также использую Xcode 4.1 на 10.7, и я знаю, что некоторые вещи с Core Data изменились на Lion. Единственная актуальная справка от Apple - недавняя сессия WWDC, которая обещает / предлагает обновленные ссылки на Apple.com, но большинство материалов Core Data очень устарели.
Для начала я использовал 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