我正在使用iOS 5.0中的新UIDocument功能.我有一个使用多个不同数据模型(momd文件)的现有应用程序.根据UIManagedDocument的文档,您可以覆盖 - (NSManagedObjectModel*)managedObjectModel来加载特定的数据模型(默认是加载所有找到的数据模型合并在一起).两个数据模型都具有重叠的模型名称和不同的模式,因此在我的情况下这是不可取的.
所以,我在一个简单的示例中遇到的问题是,我可以覆盖该函数,但我无法分配它的结果.它都是私有的,因此子类无法访问_managedObjectModel; 并且,它是只读的,因此无法分配self.managedObjectModel ..
我找到了一个覆盖managedObjectModel的UIManagedDocument示例,但Apple似乎没有提供.
我可能能够定义一个新的实例变量_myManagedObjectModel并分配它.然后返回我在覆盖的访问器上的那个.我担心的是,可能会破坏UIManagedDocument的一些内部实现,该实现不使用managedObjectModel访问器而优先于_managedObjectModel(在Apples实现中常见...)
看起来像一个直接的问题,我怀疑我只是错过了一些非常简单的东西,允许适当的覆盖.
//
// DTNoteDocument.m
// document-test
//
//
#import "DTNoteDocument.h"
@implementation DTNoteDocument
NSString * const kDataManagerModelName = @"Note";
-(NSManagedObjectModel*)managedObjectModel {
if (_managedObjectModel != nil)
return _managedObjectModel;
NSBundle *bundle = [NSBundle mainBundle];
NSString *modelPath = [bundle pathForResource:kDataManagerModelName ofType:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]]; // compile error on this line, private variable cannot be assigned
return _managedObjectModel;
}
@end
Run Code Online (Sandbox Code Playgroud)
标题:
#import <UIKit/UIKit.h>
@interface DTNoteDocument : UIManagedDocument
@end
Run Code Online (Sandbox Code Playgroud) 我正在尝试在基于UIManagedDocument的应用程序中预加载持久性存储来处理核心数据.
持久存储我尝试在应用程序B中使用,由于应用程序A"生成"并填充.在应用程序A和BI中都使用Justin Driscoll的UIManagedDocument处理程序(可在此处获得,感谢Mister Driscoll!).所有在app A中完美运行
基于此线程中解释的技术:使用UIManagedDocument在iOS 5中预加载核心数据数据库,我尝试将持久性存储放在B的应用程序包中,并在需要时将此存储复制到文档文件夹中(如果没有完成)在实例化之前的init中.
从捆绑到文档的复制都没问题(我尝试了不同的方法并通过finder和nslog检查了创建),但我无法打开"文档".应用程序不会崩溃,显示视图但表是空的(我使用与app A完全相同的代码,使用相同的fetchedResultsController).首先我认为复制持久存储是空的然后我意识到我只是无法正确打开文档/复制持久存储)=>文档状态= 5,意味着UIDocumentStateClosed和UIDocumentStateSavingError的错误(如果我正确解释它? )
(注意:我也尝试直接从bundle中实例化并打开文档,我遇到了同样的问题:doc state = 5)
所以...三天与这个文件状态= 5战斗,并没有关于修复什么的线索
我想我放入应用程序B包中的文件有问题(目前我从finder拖放到xcode,选中"为任何添加的文件夹创建文件夹引用")也许这是关于某些选项,元数据或文件权限或......
关于调查什么的任何想法?
(我不认为这是关于下面的代码但是......)这是我如何初始化(基于Justin Driscoll处理程序.只有custo是:我检查文档文件夹中是否有商店包,如果不是我创建它在捆绑中的文件)
- (id)init
{
self = [super init];
if (self) {
self.document = nil;
NSLog(@"--- INIT ---");
// On vérifie si il y a un dossier "My-Default-Document-As-Database" (notre persitent store) dans le dossier "Documents"
NSString *docDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *docFolderPath = [docDirectory stringByAppendingPathComponent:@"My-Default-Document-As-Database"];
if (![[NSFileManager defaultManager] fileExistsAtPath:docFolderPath]) {
NSError *error = nil;
NSLog(@"Pas …Run Code Online (Sandbox Code Playgroud) 我找到了这些斯坦福大学的教程https://itunes.apple.com/us/course/ipad-iphone-app-development/id495052415,并且一直在听关于核心数据的讲座,这真的很棒.
它显示了如何通过UIManagedDocument... 访问核心数据只有我不明白UIManagedDocument它应该知道它应该使用哪个模型,因为我没有看到它设置在任何地方?
在使用时总结一下UIManagedDocument,如何定义将要使用的数据库模型?
我正在开发一个使用子类的iPhone应用程序,UIManagedDocument并将其文档存储在iCloud上.
在改变我的核心数据模型/方案(添加一个新的模型版本 - 就像我在过去几周里曾多次)之前,一切正常.我添加了一个新属性并更改了其中一个现有属性的数据类型.
现在,当我跑我的应用我似乎并没有能够加载我的文档用UIManagedDocument的-openWithCompletionHandler:.我可以创建新文档并读/写.如果我将数据模型版本改回1,那么我可以阅读现有文档,但不能阅读新文档.
根据我的理解,我只对数据模型进行轻量级迁移,并且UIManagedDocument应该处理这个问题吗?
任何建议将不胜感激!
当我在下面声明代码语句时,为什么会出现此错误?
使用未声明的标识符'NSMigratePersistentStoresAutomaticallyOption'
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
Run Code Online (Sandbox Code Playgroud)
为了让我能够识别我的NSMigratePersistentStoresAutomaticallyOption常量,我缺少什么?
谢谢,
麦克风
我正在从后台队列创建并向Core Data添加大量托管对象.我的理解是我无法从后台线程访问上下文,所以我使用performBlock来安排将Core Data添加回创建上下文的同一队列.这很好用......
我的问题是在测试期间我注意到通过删除[moc performBlock:^{ ... }];应用程序仍然按预期执行(甚至可能快一秒钟)我需要performBlock吗?我会假设我这样做并且正在以非线程安全的方式工作(现在:),我只是想检查以确保我的理解没有缺陷.
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(backgroundQueue, ^{
// GET DATA
// PROCESS DATA
NSManagedObjectContext *context = [[self managedDocument] managedObjectContext];
[moc performBlock:^{
// ADD TO CORE DATA
[Core createRodInContext:context withDictionary:fuelRodDictionary];
}];
});
Run Code Online (Sandbox Code Playgroud)
编辑:为createRodInContext添加了实现...
+ (Rod *)createRodInContext:(NSManagedObjectContext *)context withDictionary:(NSDictionary *)dictionary {
// CREATE
Rod *rod = [NSEntityDescription insertNewObjectForEntityForName:@"Rod" inManagedObjectContext:context];
// POPULATE
[neo setDataCode:[dictionary objectForKey:@"dataCode"]];
[neo setDataName:[dictionary objectForKey:@"dataName"]];
[neo setDataReference:[dictionary objectForKey:@"dataReference"]];
...
return rod;
}
Run Code Online (Sandbox Code Playgroud) iphone cocoa-touch objective-c grand-central-dispatch uimanageddocument
我正在尝试设置核心数据,但是当我正在运行saveToURL时,UIManagedDocument它无法创建它.这是我的代码;
@property (nonatomic, strong) UIManagedDocument *currentUserDatabase;
@synthesize currentUserDatabase = _currentUserDatabase;
- (void)setCurrentUserDatabase:(UIManagedDocument *)currentUserDatabase
{
_currentUserDatabase = currentUserDatabase;
[self useDocument];
}
- (void)isUserLoggedIn
{
if (!self.currentUserDatabase) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentationDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Current User Database"];
self.currentUserDatabase = [[UIManagedDocument alloc] initWithFileURL:url];
}
}
- (void)useDocument
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.currentUserDatabase.fileURL path]]) {
[self.currentUserDatabase saveToURL:self.currentUserDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if (success) {
NSLog(@"create success");
} else {
NSLog(@"create failed");
}
//[self getCurrentUser];
}]; …Run Code Online (Sandbox Code Playgroud) 我不确定coreData的结构以及如何将对象保存在目录中.所以我所知道的是你创建了一个UIManagedDocument的实例并为它创建一个URL以及它将保存文件的位置.那么你打电话给"SaveToURL",你打电话给它的确是什么?它是核心数据堆栈吗?然后,当您将信息保存到实体中时,您声明的是在实体中为每组信息在堆栈中创建的单独文件?最后,UIManagedDocument的上下文究竟是什么.
这是三个主要问题
我在整个应用程序(有两个实体)中有一个托管文档,用户可以从两个不同的视图控制器进行更新.每个视图控制器都有自己的NSFetchedResultsController属性,用于将更改中继到:一个视图控制器中的UICollectionView和另一个视图控制器中的UITableView.根视图控制器中的UICollectionView显示Teams,而segued视图控制器中的UITableView显示该团队中的Players.
当我在第一个视图控制器中时,我可以添加一个团队的实例,它可以正常工作,因为它将它们保存到文档中,然后将它们添加到UICollectionView.当我在第二个视图控制器中时,我将一个Player插入CoreData并调用:
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];
Run Code Online (Sandbox Code Playgroud)
这正确地调用了NSFetchedResultsControllerDelegate方法: - (void)controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
在这个委托方法中,我打电话给:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
Run Code Online (Sandbox Code Playgroud)
但是,在表视图上调用此行插入方法会导致以下Core Data错误:
"CoreData:错误:严重的应用程序错误.在Core Data更改处理期间捕获到异常.这通常是NSManagedObjectContextObjectsDidChangeNotification的观察者中的错误. * - [__ NSPlaceholderArray initWithObjects:count:]:尝试从对象[0]插入nil对象userInfo(null)"
我的fetchedResultsController肯定是NSManagedObjectContextObjectsDidChangeNotification的观察者,但是在托管对象上下文中的任何更改之前发生此错误.所以我基本上无法确定托管对象上下文在哪一点获得null userInfo.
(另一件事情是我的NSFetchedResultsController来自根视图控制器,它有UICollectionView,在下一个具有UITableView的视图控制器中的NSFetchedResultsController之前触发其委托方法,触发它自己.我认为这是正确的功能,因为团队和玩家都在获得CoreData的更新.
有关为什么UITableView行插入导致此错误的想法,或者我的单个托管文档可能会导致可能导致此问题的不一致的问题?
core-data nsfetchedresultscontroller ipad ios uimanageddocument
我向我的所有实体添加了一个lastModifiedDate属性,以避免在UIManagedDocument与iCloud 同步时出现重复,我发现如果我使用离线设备(iPad)创建新实体,并且同时使用创建相同的实体,我会发生这种情况另一个在线设备(iPhone).
我想在对象发生变化时设置此属性,以便我订阅NSManagedObjectContextObjectsDidChangeNotification.我编写的用于设置lastModifiedDate的代码创建了一个无限循环,因为通过设置lastModificationDate属性,它创建了一个更改,NSManagedObjectContextObjectsDidChangeNotification等将再次通知它...
有可能解决它吗?有没有更好的方法来实现我的目标?我应该将managedObjectContext子类化并覆盖willSave:吗?
//At init...
[[NSNotificationCenter defaultCenter] addObserver:applicationDatabase
selector:@selector(objectsDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:applicationDatabase.managedDocument.managedObjectContext];
(void) objectsDidChange: (NSNotification*) note
{
// creates an infinite loop
NSDate *dateOfTheLastModification = [NSDate date];
NSMutableArray *userInfoKeys = [[note.userInfo allKeys] mutableCopy];
for(int i=0; i< userInfoKeys.count;i++){
NSString *key = [userInfoKeys objectAtIndex:i];
if([key isEqualToString:@"managedObjectContext"]){
[userInfoKeys removeObject:key];
}
}
for(NSString *key in userInfoKeys){
NSArray *detail = [note.userInfo objectForKey:key];
for (id object in detail){
[object setValue:dateOfTheLastModification forKey:@"lastModifiedDate"];
}
}
Run Code Online (Sandbox Code Playgroud)