观察对象未注册为观察者
当我的数组控制器刷新了从服务器请求中检索的新数据时,我遇到了问题。观察对象未注册为观察者
的设置
我有一个实体对象(称之为MyParent
),其中有几个特性:
name age description widgetID
并且具有一些属性的实体对象(称之为进myWidget):
name size description
大小是一个NSSize
对象的字符串表示。它使得从核心数据存储和服务器轻松存储和检索,并返回到JSON。为了表示UI中的大小,我已经将MyWidget子类化并提供了一个自定义setter和getter作为自定义类的类别(我这样做是为了让Xcode不会覆盖我的更改,如果我需要更改模型):
-(void)setObjectWidth:(NSInteger)aValue {
[self setObjectSize:NSMakeSize(aValue, [self objectHeight])];
}
-(void)setObjectHeight:(NSInteger)aValue {
[self setObjectSize:NSMakeSize([self objectWidth], aValue)];
}
-(void)setObjectSize:(NSSize)aValue {
[self setSize:NSStringFromSize(aValue)];
}
-(NSInteger)objectWidth {
return [self objectSize].width;
}
-(NSInteger)objectHeight {
return [self objectSize].height;
}
-(NSSize)objectSize {
return NSSizeFromString([self size]);
}
我做的widgetId
查找作为父类别方法得到widget
:
-(MyWidget *)widget {
NSManagedObjectContext * moc = [[NSApp delegate] managedObjectContext];
return [moc fetchObjectForEntityName:@"MyWidget"
withUID:[self widgetID]];
}
的fetchObjectForEntityName:withUID是在管理对象方面类别。
在UI中我有一个数组控制器绑定到MyParent
对象的tableView。选择对象呈现被绑定到适当的值在用户界面中的细节:
parentArrayController --> parentArray (managed objects in an array) parentTable --> parentArrayController.arrangedObjects.name uiWidthTextField --> parentArrayController.selection.widget.objectWidth uiHeightTextField --> parentArrayController.selection.widget.objectHeight
阵列控制器被观察到的变化,使得它可以发射关闭相应需要知道该应用程序的其它部分的通知选择的对象改变
什么工作
一切运作良好。我可以对用户界面中的文本字段进行更改,并根据您的需要设置和获取小部件的大小。添加父项是创建NSURLConnection并将适当的参数发送到服务器的简单任务。当服务器确认添加时,我再次请求父服务器的列表。
下来的列表将与核心数据中的现有列表进行比较,并添加新项目并对已存在的其他对象值进行任何其他更改。
什么地方不对头
当列表回来,它被正确解析,但应用程序抱怨时,阵列控制器被更新:
严重的应用程序错误。核心数据更改处理期间发生异常:无法从关键路径“widget.objectHeight”中删除观察者,因为它未注册为观察者。 with userInfo(null)
无法删除关键路径“widget.objectHeight”的观察者,因为它没有注册为观察者。
我已经试过
我已尝试添加一个willChangeValueForKey:和didChangeValueForKey:缠objectHeight和objectWidth的二传手,但这似乎不提供追索权。
我相信这个问题是因为IB绑定到widget.objectHeight
,而widget是父级查询,而不是真正的KVO/KVC属性。不过,我并不需要widget
上的二传手(尽管我会在下一步尝试)。
我知道我错过了一些东西,但不能把我的手指放在上面。
的抗辩
任何帮助或协助解决这项援助将非常感谢!
您需要将objectWidth
和objectHeight
设置为MyWidget的非模型属性。您遇到KVO问题,因为objectWidth
和objectHeight
不是MyWidget的键,只是以getter和setter的形式拥有方法名称。
只需添加:
@property() NSInteger objectWidth;
@property() NSInteger objectHeight;
到进myWidget类和应提供志愿工作的关键。 (可能要仔细检查我的财产形式,这是一段时间的感觉,我不得不写一个整数属性。)
感谢您的回应。我试着给模型添加@property,但它没有什么区别。然后用适当的willChangeValue和willAccessValue包装每个setter/getter。没有快乐。然后我将这些从类别中直接移到模型对象上。仍然没有运气:-(尽我所能说它是失败的,正如你指出的那样,这是有道理的,我也尝试用automaticNotifiesObserversForKey禁用自动通知,并为这些键返回NO(objectHeight等)。 – Hooligancat 2011-04-12 23:46:04
终于回过头来解决我的问题,你的解决方案工作,我没有意识到,我已经设置了setter和getters不做自动通知,因此合成的setter和getter没有发射KVC通知。工作得很好,谢谢! – Hooligancat 2011-05-12 23:38:51