gpt4 book ai didi

ios - 具有 KVO View Controller 和基于手势的更改的核心数据对象

转载 作者:行者123 更新时间:2023-11-29 03:16:30 25 4
gpt4 key购买 nike

我有一个 iPhone/iPad 应用程序,其中一个主要功能是在绘图上排列对象。我使用 Core Data 来管理对象的关系;对于这个例子,我将讨论 Units,它与 Plot 具有一对一的关系(以及一对多的逆关系)。单位的属性包括 positionX、positionY 和 angle。

每个单元(继承自 NSManagedObject)都与一个 UnitViewController(继承自 UIViewController)配对。 Unit 有一个属性.viewController,UnitViewController 有一个属性.object,因此在不同的用途中它们可以相互引用。这些是在打开绘图或添加新单位(或从撤消重新添加等)时设置的。

每个 UnitViewController 都有一个用于其 View 的 UIPanGestureRecognizer,当该手势发生时,UnitViewController 会更改其 .object 的 positionX 和 positionY 值。当发生这种情况时,UnitViewController 然后通过 KVO 观察这些变化并重新定位 View 。

这可能看起来很复杂,但我这样做的原因是我还可以在 UITableView 中以数字方式更改位置。这是代码的简化版本,显示了路径的关键部分。其中一些方法存在于我的 UIViewController+LD 类别中,因此是通用名称。

- (IBAction)dragObject:(UIPanGestureRecognizer *)gesture
{
// GESTURE BEGAN
if ([gesture state] == UIGestureRecognizerStateBegan) {
[self beginGesture:gesture];
if (!_selected) [self setSelected:YES];
}

// turn on registration before last pass
if ([gesture state] == UIGestureRecognizerStateEnded || [gesture state] == UIGestureRecognizerStateCancelled) {
[[NSNotificationCenter defaultCenter] postNotificationName:ENABLE_UNDO_REGISTRATION object:nil];
}

// MOVE
[self dragUnitWithGesture:gesture];

// turn off registration after first pass
if ([gesture state] == UIGestureRecognizerStateBegan) {
[[NSNotificationCenter defaultCenter] postNotificationName:DISABLE_UNDO_REGISTRATION object:nil];
}

// GESTURE ENDED
if ([gesture state] == UIGestureRecognizerStateEnded ||
[gesture state] == UIGestureRecognizerStateCancelled) {
[self endGesture];
}
}

- (void)dragUnitWithGesture:(UIPanGestureRecognizer *)gesture
{
CGPoint translation = [gesture translationInView:self.view.superview];
[self saveNewObjectCenterWithTranslation:translation];
}

- (void)saveNewObjectCenterWithTranslation:(CGPoint)translation
{
[self saveNewObjectCenter:CGPointMake(initialCenter.x + translation.x, initialCenter.y + translation.y)];
}

- (void)saveNewObjectCenter:(CGPoint)center
{
CGPoint dataPoint = [Converter dataPointFromViewPoint:center];
self.object.positionX = [NSNumber numberWithFloat:dataPoint.x];
self.object.positionY = [NSNumber numberWithFloat:dataPoint.y];
}

- (void)beginGesture:(UIGestureRecognizer *)gesture
{
[[NSNotificationCenter defaultCenter] postNotificationName:BEGIN_UNDO_GROUPING object:nil];

self.initialCenter = self.view.center;
}

- (void)endGesture
{
NSError *error = nil;
[self.object.managedObjectContext save:&error];

[[NSNotificationCenter defaultCenter] postNotificationName:END_UNDO_GROUPING object:nil];
}

我的问题来自通过 Crashlytics 获得的崩溃报告,因为我无法在我的设备上复制崩溃。有多个报告都与堆栈跟踪一起发生:

_UIGestureRecognizerSendActions
-[UnitViewController dragObject:]
-[UnitViewController dragUnitWithGesture:]
-[UnitViewController saveNewObjectCenterWithTranslation:]
-[UIViewController(LD) saveNewObjectCenter:]
_sharedIMPL_setvfk_core + 110
-[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] + 180
NSKeyValueWillChange + 474
NSKeyValuePushPendingNotificationPerThread + 214

这个特别的结束于:

Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000000

但我也看到了:

Fatal Exception: NSInternalInconsistencyException
An -observeValueForKeyPath:ofObject:change:context: message was received but not handled (keyPath: positionX)

Fatal Exception: NSObjectInaccessibleException
Core Data could not fulfill a fault for ‘0x00000000 <x-coredata://xxxxxx/Unit/p116>'

所以我的问题是:这种类型的数据修改是否存在已知问题? Core Data 框架是否处理得太快了?或者还有其他我可能做错的事情吗?这个问题只是 Core Data 问题在我的应用程序中出现的其中一种方式,我很乐意深入了解问题的核心,使我的应用程序更加稳定。

更新:我没有足够的声誉来发布图片,但这里有一个指向完整堆栈跟踪的链接: stackTrace

最佳答案

尽管我同意 Marcus 关于减少 save: 调用次数的精神,但我不相信 save: 频率是造成这种情况的根源特殊问题,因为它仅在平移手势结束时调用。

相反,崩溃日志屏幕截图看起来非常像 KVO 观察者已被释放,而没有首先作为观察者被删除。

检查您的代码并确保所有 addObserver:forKeyPath:context: 调用均通过 removeObserver:forKeyPath:context: 进行平衡,并且您的观察者不可能做到这一点( s) 在不首先取消他们的遵守的情况下被释放。

如果您找不到可能出错的地方,那么也许可以编辑您的问题以包含与 KVO 相关的代码,以便我们可以查看它。

至于无法实现错误异常,这是一个不同的问题,可能需要一个不同的堆栈溢出问题,并包含完整的堆栈跟踪。

关于ios - 具有 KVO View Controller 和基于手势的更改的核心数据对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21630596/

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