OS X编程新手。开始使用带有Core Data的基于文档的应用程序的Xcode模板。
在我的默认Document.xib中,我创建了一个View
,我使用自定义ViewController
进行控制。然后我在Document.xib中创建了一个Managed Object Context
,并创建了两个出口,一个出口到Document.h
:
@property (strong) IBOutlet NSManagedObjectContext *myManagedObjectContext;
和一个ViewController.h
:
@property (weak) IBOutlet NSManagedObjectContext *myManagedObjectContext;
在windowControllerDidLoad
的{{1}}中,我添加了Document.m
。
按照ghostfly的建议(could not locate an NSManagedObjectModel for entity name),我补充道:
self.myManagedObjectContext = [self managedObjectContext]
到NSLog(@"Context: %@",self.myManagedObjectContext);
NSLog(@"PS Coord : %@",self.myManagedObjectContext.persistentStoreCoordinator);
NSLog(@"MOM : %@", self.myManagedObjectContext.persistentStoreCoordinator.managedObjectModel);
NSLog(@"Entities : %@",[[self.myManagedObjectContext.persistentStoreCoordinator.managedObjectModel entities] valueForKey:@"name"]);
中的Document.m以及我的ViewController的windowControllerDidLoad
。在Document.m中,一切似乎都运行良好:所有NSLog语句看起来都正确,我也可以将实体添加到我的NSManagedObjectContext中,但是在ViewController中,只有第一个NSLog语句有效,其余的返回(null)。
我的问题:这里出了什么问题,我是否以正确的方式解决这个问题?
其他各种问题似乎都建议将AppDelegate添加到awakeFromNib
,但我不确定这在基于文档的应用程序中是如何实现的(例如,我希望每个文档都有一个单独的MainMenu.xib
,但如果我使用AppDelegate,那么它们肯定都是一样的吗?),或者即使这是推荐的,因为有些教程建议明确不如何做到这一点(例如这里http://franck.verrot.fr/blog/2012/01/18/best-way-to-pass-nsmanagedobjectcontext-around-in-ios-applications/)。非常感谢帮助!感谢。
答案 0 :(得分:1)
编辑:正确答案是使用MagicalRecord(https://github.com/magicalpanda/magicalrecord)并节省一大堆时间!
我之前的回答如下:
好吧,我认为我已经有了这个工作,但我不确定这是否是“最佳”或“最惯用”的方式。我将以极其详细的方式详细说明,以防万一其他人偶然发现这个问题而且同样难以理解这一切是如何融合在一起的......
首先,忘记.xib中的ManagedObjectContext;我不确定何时使用它。
我创建了一个名为AppDelegate的应用程序委托。在AppDelegate.h
:
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (retain) NSManagedObjectContext *managedObjectContext;
@property (retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@end
然后,在MainMenu.xib
中,我拖入NSObject
并将其类设置为AppDelegate
,并将文件所有者的委托连接到此对象。
在Document.m
中,在init
方法中,我添加:
AppDelegate *appDelegate = (AppDelegate*)[[NSApplication sharedApplication] delegate];
appDelegate.managedObjectContext = [self managedObjectContext];
appDelegate.persistentStoreCoordinator = [self managedObjectContext].persistentStoreCoordinator;
请注意,我最初尝试将其放在windowControllerDidLoadNib
方法中,但这不起作用,因为在我的ViewController
之后,它似乎被称为 { {1}}方法。
然后,在awakeFromNib
ViewController.m
awakeFromNib
中,我可以通过以下方式访问上下文:
AppDelegate *appDelegate = (AppDelegate*)[[NSApplication sharedApplication] delegate];
MyEntity *test = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:[appDelegate managedObjectContext]];
如果我在接下来的几天内没有发现任何问题,我会接受这个答案。
一个悬而未决的问题是当我打开多个文档时会发生什么。他们都会分享相同的背景吗?
答案 1 :(得分:1)
当您开始使用多个文档时,上述答案会产生问题 - 它将无法正常工作,因为您只保存到上次打开的文档。您不应该尝试创建自己的托管对象上下文,因为那时您必须设置存储数据的所有内容等(已经完成)。它更简单:
您的主文档类应该是NSPersistentDocument的子类。如果没有,那么你可以直接替换它而不是NSDocument。 NSPersistentDocument具有自己的managedObjectContext和persistentStoreCoordinator,您可以在文档中使用它(用于存储文档相关数据)。
因此,这意味着每个文档都有自己的managedObjectContext和persistentStoreCoordinator。要在其他类中访问它们,您应该将引用传递给文档。例如。在您的视图控制器子类上,为文档创建一个@IBOutlet,在接口构建器中附加文档,然后在构造函数中,将文档的managedobjectcontext复制到它在视图控制器中自己的指针以供使用。