xcode - 创建新的基于文档的核心数据项目时出现问题

标签 xcode macos cocoa core-data

我正在尝试创建一个基于核心数据的 Mac OS X 应用程序。我在 iOS 上使用了 Core Data,但 AppKit 的情况有些不同。我也在 10.7 上使用 Xcode 4.1,并且我知道 Lion 上的一些核心数据已经发生了变化。 Apple 唯一的最新引用资料是最近的 WWDC session ,该 session promise /建议在 Apple.com 上更新引用资料,但大多数核心数据内容都非常过时。

首先,我使用 Xcode 使用 Core Data 生成一个基于文档的项目。我掏空了一些主菜单位(删除了一些菜单项)并摆脱了 NSWindow里面的物体Main Menu.xib ,创建我自己的MyDocument.xibNSWindow (和 subview )。

问题:

  1. 我假设持久存储 Controller 始终需要持久存储,因此如果创建新文档,我只需添加一个内存存储。从磁盘打开时,我使用 SQLite 存储创建它。这是正确的吗?

  2. 我(表面上)在 writeToURL:ofType:error: 中进行了商店迁移如果url是不同的。但是如果我在 writeToURL:ofType:error: 设置断点,然后点击保存,我的断点没有命中。为什么不呢?

  3. 如果我选择“恢复到已保存”,应用程序就会严重崩溃。我必须强制退出它(并退出 Xcode)。为什么?

  4. (非常)旧的视频教程提出了一种轻松将数据绑定(bind)到 UIView 的方法。就像一张 table 。跟随 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

最佳答案

如果您使用的是 NSPersistentDocument,默认情况下所有这些都会为您处理,您无需进行任何核心数据设置。 NSPercientDocument 将自动处理持久存储的创建、保存和迁移。

如果您想控制持久存储的配置方式,只需覆盖

-configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:

然后,您可以在需要时向文档询问其managedObjectContext,然后编写代码。

我强烈建议您阅读 Apple 的 NSPersistentDocument tutorial了解更多详情。

关于xcode - 创建新的基于文档的核心数据项目时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7409546/

相关文章:

iphone - 我可以修复崩溃,但我不明白为什么会这样

ios - xcode快捷键导入h文件并添加Delegate方法

java - 什么是java android开发的最佳IDE

macos - 您如何在 MATLAB 和 OS X 中使用 xlsread?

Xcode 8导入pdf(矢量)介绍图像 Assets 无法正常工作

swift - 字符串之间带有标记的 XMLElement

ios - 如何使用 cocoa pod 安装 Google Api

objective-c - 在我的自定义 NSSlider 中使用 CoreGraphics 进行 Cocoa 绘图时出现错误

objective-c - 在 Objective-C 中保存空白文件

ios - 如何删除 UITableViewCell 第一行的垂直间距