观察对象未注册为观察者

时间:2011-04-12 18:34:35

标签: objective-c core-data cocoa-bindings nsmanagedobject nsarraycontroller

当使用从服务器请求中检索到的新数据刷新我的阵列控制器时,我遇到了问题。

设置

我有一个实体对象(称之为MyParent),它有一些属性:

name
age
description
widgetID

一个实体对象(称之为MyWidget),它有一些属性:

name
size
description

size是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]);
}

我通过在widget上查找作为父级的类别方法来获取widgetId

-(MyWidget *)widget {
    NSManagedObjectContext * moc = [[NSApp delegate] managedObjectContext];

    return [moc fetchObjectForEntityName:@"MyWidget"
                                 withUID:[self widgetID]];
}

fetchObjectForEntityName:withUID是托管对象上下文中的一个类别。

在UI中,我有一个绑定到MyParent个对象的tableView的数组控制器。选择对象会在UI中显示绑定到适当值的详细信息:

parentArrayController --> parentArray (managed objects in an array)
parentTable --> parentArrayController.arrangedObjects.name

uiWidthTextField --> parentArrayController.selection.widget.objectWidth
uiHeightTextField --> parentArrayController.selection.widget.objectHeight

观察阵列控制器的变化,以便它可以触发应用程序中需要知道所选对象已更改的其他部分的通知

什么有用

一切都运作良好。我可以对UI中的文本字段进行更改,并根据您的预期设置并从窗口小部件中获取大小。添加父项是一项简单的任务,即创建NSURLConnection并将相应的参数发送到服务器。当服务器确认添加时,我再次从服务器请求父项列表。

将下来的列表与核心数据中的现有列表进行比较,并添加新项目并对已存在的其他对象值进行任何其他更改。

什么是破碎

当列表返回时,它被正确解析,但应用程序在更新阵列控制器时会抱怨:

  

严重的应用程序错误。在Core Data更改处理期间捕获到异常:无法删除关键路径“widget.objectHeight”的观察者,因为它未注册为观察者。 with userInfo(null)

     

无法删除关键路径“widget.objectHeight”的观察者,因为它未注册为观察者。

我尝试过什么

我试图添加一个willChangeValueForKey:和didChangeValueForKey:包裹在objectHeight和objectWidth的setter中,但这似乎没有提供任何追索权。

我认为问题是因为IB绑定到widget.objectHeight并且widget是对父级的查找,而不是真正的KVO / KVC属性。但是,我不需要widget上的setter(虽然我接下来会尝试)。

我知道我错过了什么,但不能把手指放在上面。

辩诉

非常感谢您解决此问题的任何帮助或帮助!

1 个答案:

答案 0 :(得分:0)

您需要将objectWidthobjectHeight设置为MyWidget的非建模属性。您遇到了KVO问题,因为objectWidthobjectHeight不是MyWidget的键,而是只有getter和setter形式的方法名称。

只需添加:

@property() NSInteger objectWidth;
@property() NSInteger objectHeight;

到MyWidget类,它应该为KVO提供工作的密钥。 (可能想要仔细检查我的属性表单。已经有一段时间了,我必须写一个整数属性。)

相关问题