Iphone NSUndoManager撤消不使用核心数据
我正在尝试创建一个iPhone应用程序,用户可以在其中添加条目。当他按下一个新条目时,会弹出一个框,询问他一些信息。然后他可以按“取消”或“保存”放弃数据或将其保存到磁盘 为了节省开支,我使用了核心数据框架,它工作得很好。但是,我无法让“取消”按钮工作。当弹出窗口询问信息时,我在托管对象上下文(MOC)中创建一个新对象。然后,当用户按下cancel时,我尝试使用属于MOC的NSUndoManager 我还希望使用嵌套的撤消组来执行此操作,因为可能存在嵌套组 为了测试这一点,我编写了一个简单的应用程序。该应用程序只是启用了核心数据的“基于窗口的应用程序”模板。对于核心数据模型,我创建了一个名为“entity”的实体,其整数属性为“x”。然后在ApplicationIDFinishLaunching中添加以下代码:Iphone NSUndoManager撤消不使用核心数据,iphone,undo,nsmanagedobject,nsundomanager,Iphone,Undo,Nsmanagedobject,Nsundomanager,我正在尝试创建一个iPhone应用程序,用户可以在其中添加条目。当他按下一个新条目时,会弹出一个框,询问他一些信息。然后他可以按“取消”或“保存”放弃数据或将其保存到磁盘 为了节省开支,我使用了核心数据框架,它工作得很好。但是,我无法让“取消”按钮工作。当弹出窗口询问信息时,我在托管对象上下文(MOC)中创建一个新对象。然后,当用户按下cancel时,我尝试使用属于MOC的NSUndoManager 我还希望使用嵌套的撤消组来执行此操作,因为可能存在嵌套组 为了测试这一点,我编写了一个简单的应用
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
unsigned int x=arc4random()%1000;
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager beginUndoGrouping];
NSManagedObject *entity=[NSEntityDescription insertNewObjectForEntityForName:@"Entity"
inManagedObjectContext:self.managedObjectContext];
[entity setValue:[NSNumber numberWithInt:x] forKey:@"x"];
NSLog(@"Insert Value %d",x);
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager endUndoGrouping];
[self.managedObjectContext.undoManager undoNestedGroup];
NSFetchRequest *fetchRequest=[[NSFetchRequest alloc] init];
NSEntityDescription *entityEntity=[NSEntityDescription entityForName:@"Entity"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entityEntity];
NSArray *result=[self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
for(entity in result) {
NSLog(@"FETCHED ENTITY %d",[[entity valueForKey:@"x"] intValue]);
}
[window makeKeyAndVisible];
}
这个想法很简单。尝试插入一个新的实体对象,撤消它,获取MOC中的所有实体对象并打印出来。如果一切正常,最后应该没有对象
但是,我得到了以下输出:
[Session started at 2010-02-20 13:41:49 -0800.]
2010-02-20 13:41:51.695 Untitledundotes[7373:20b] Insert Value 136
2010-02-20 13:41:51.715 Untitledundotes[7373:20b] FETCHED ENTITY 136
如您所见,在我尝试撤消其创建后,对象出现在MOC中。
关于我做错了什么,有什么建议吗?您的问题是因为与OS X不同,iPhone托管对象上下文默认不包含撤消管理器。您需要显式地添加一个 将managedObjectContext属性的应用程序委托中生成的代码更改为如下所示:
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
//add the following 3 lines of code
NSUndoManager *undoManager = [[NSUndoManager alloc] init];
[managedObjectContext setUndoManager:undoManager];
[undoManager release];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
进行更改后,将不再打印第二条日志消息
希望这有助于
戴夫我尝试了戴夫的方法,但不适合我。 我终于在苹果的例子中找到了解决方案 诀窍是创建一个新的上下文,与应用程序的上下文共享协调器。要放弃更改,您不需要做任何事情,只需放弃新的上下文对象即可。由于您共享协调器,保存将更新您的主上下文 这是我的改编版本,其中我使用一个静态对象作为临时上下文来创建一个新的ChannelMO对象
//Gets a new ChannelMO that is part of the addingManagedContext
+(ChannelMO*) getNewChannelMO{
// Create a new managed object context for the new channel -- set its persistent store coordinator to the same as that from the fetched results controller's context.
NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
addingManagedObjectContext = addingContext;
[addingManagedObjectContext setPersistentStoreCoordinator:[[self getContext] persistentStoreCoordinator]];
ChannelMO* aux = (ChannelMO *)[NSEntityDescription insertNewObjectForEntityForName:@"ChannelMO" inManagedObjectContext:addingManagedObjectContext];
return aux;
}
+(void) saveAddingContext{
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
[dnc addObserver:self selector:@selector(addControllerContextDidSave:)
name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];
NSError *error;
if (![addingManagedObjectContext save:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];
// Release the adding managed object context.
addingManagedObjectContext = nil;
}
我希望有帮助
Gonso它应该会起作用。是否已将撤消管理器正确分配给managedObjectContext?如果您正确地做到了这一点,那么默认情况下它已经启用了撤消注册,您应该可以开始了。有一篇关于核心数据的好文章。有一个关于核心数据和NSUndoManager的好教程。希望能有帮助。嗨,我也有同样的问题。你找到解决办法了吗?您是否尝试过使用“撤消”而不是“撤消嵌套组”?谢谢Gonso在谷歌搜索类似问题时发现了这个问题。Dave,我想有一个很好的理由,默认情况下undoManager为零?比如,如果我继续实施这个,我是否会遇到与内存相关的问题?如果您的保存失败怎么办?您将如何撤消那些已经放入上下文中并导致失败的更改?例如,验证。