gpt4 book ai didi

objective-c - 如何将 undoManager 与核心数据实体一起使用

转载 作者:行者123 更新时间:2023-12-02 07:41:51 26 4
gpt4 key购买 nike

我有一个名为 appointment 的 NSManagedObject,我编辑了它的属性。如果我的用户按下取消,我想撤消所有这些编辑。

如果我这样做(示例代码)

[[appointment managedObjectContext] setUndoManager:[[NSUndoManager alloc] init]]; //however doing a nslog on undoManager still shows it as (null);
[[[appointment managedObjectContext] undoManager] beginUndoGrouping];
appointment.startTime = 11;
appointment.endTime = 12;
appointment.customer = @"Tom";
[[[appointment managedObjectContext] undoManager] endUndoGrouping];
[[[appointment managedObjectContext] undoManager] undo];

它不应该撤消 beginUndoGroupingendUndoGrouping 之间的所有更改吗?似乎有很多方法可以做到这一点,但我似乎找不到正确的方法。撤消对 NSManagedObject 的更改的正确方法是什么?

最佳答案

我认为这只是事件进行顺序的示例,而不是实际示例。

你是不是偶然忘记给 ManagedObjectContext 一个 NSUndoManager?

我相信你在 OS X 下默认获得一个,但在 iOS 下,你必须专门提供一个。

您要确保在创建 MOC 时设置撤消管理器...

managedObjectContext.undoManager = [[NSUndoManager alloc] init];

如果 undo-manager 为 nil,那么在执行此操作后,您正在使用多个 MOC,或者其他一些代码已将其重置。

此外,为了调试的目的,检查 appointment.managedObjectContext 属性,并确保它不为 nil 并引用有效的 MOC。

编辑

好的,我只是去写了一个快速测试,使用了一个简单的模型。也许您应该做一些类似的事情来查看您的断言在哪里失败(您可以在代码路径中添加普通断言 - 我将此作为单元测试进行,因此我可以轻松地将其添加到现有项目中)。

- (void)testUndoManager
{
NSDate *now = [NSDate date];
NSManagedObjectContext *moc = [self managedObjectContextWithConcurrencyType:NSConfinementConcurrencyType];
STAssertNil(moc.undoManager, @"undoManager is nil by default in iOS");
moc.undoManager = [[NSUndoManager alloc] init];
[moc.undoManager beginUndoGrouping];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:EVENT_ENTITY_NAME inManagedObjectContext:moc];
STAssertNotNil(moc, @"Managed Object is nil");
STAssertEquals(moc, object.managedObjectContext, @"MOC of object should be same as MOC");
STAssertNotNil(object.managedObjectContext.undoManager, @"undoManager of MOC should not be nil");
[object setValue:now forKey:@"timestamp"];
STAssertEqualObjects(now, [object valueForKey:@"timestamp"], @"Timestamp should be NOW");
[moc.undoManager endUndoGrouping];
STAssertEqualObjects(now, [object valueForKey:@"timestamp"], @"Timestamp should be NOW");
[moc.undoManager undo];
STAssertNil([object valueForKey:@"timestamp"], @"Object access should be nil because changes were undone");
}

编辑

在几种情况下,托管对象的 MOC 可以设置为 nil。例如,如果您删除一个对象,然后保存 mod,则该对象的 MOC 将被设置为 nil...

NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"SomeEntity" inManagedObjectContext:moc];
[object.managedObjectContext deleteObject:object];
[moc save:0];
// object.managedObjectContext will be nil

另一种不太常见的情况,但表明 MOC 可能存在内存问题......在 ARC 下,托管对象的 MOC 是一个弱指针。因此,如果 MOC 消失,该指针将重置为 nil。在非 ARC 下,指针将只有旧值,您的结果将是未定义的……可能是崩溃。

因此,如果 managedObject.managedObjectManager 为 nil,则最可能的罪魁祸首是:

  1. 该对象从未插入到 MOC 中
  2. 对象已从 MOC 中删除
  3. MOC 已删除

关于objective-c - 如何将 undoManager 与核心数据实体一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10304121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com