多对多关系中的 KVO 对象属性

发布于 2024-12-19 02:26:17 字数 392 浏览 3 评论 0原文

我有一个核心数据对多关系,其中包含 Parent <--->>孩子。我想设置一个键值观察机制,以便当任何子对象上的属性(例如,firstName、lastName)更改时,它会触发通知。当使用标准 KVO 语法时:

[self.parentObject addObserver:self forKeyPath:@"children" options:NSKeyValueObservingOptionNew context:NULL]

这仅在关系本身被修改时发出通知(即,在关系中添加或删除子对象),而不是在这些子对象之一的属性发生更改时发出通知。显然这就是它的设计运行方式,所以发生这种情况没有任何问题,但是我怎样才能使用 KVO 来实现我想要的要求呢?

提前致谢!

I have a Core Data to-many relationship consisting of Parent <--->> Child. I would like to setup a key-value observing mechanism such that when a property (e.g. firstName, lastName) on any of the Child objects changes it triggers a notification. When using the standard KVO syntax:

[self.parentObject addObserver:self forKeyPath:@"children" options:NSKeyValueObservingOptionNew context:NULL]

this only notifies when the relationship itself is modified (i.e. a Child object is added or removed from the relationship), rather than when a property of one of those Child objects changes. Obviously this is how it was designed to operate, so there's nothing wrong with that happening, but how can I instead use KVO to achieve my desired requirement?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ˉ厌 2024-12-26 02:26:17

AFAIK 没有内置方法可以用一行代码观察集合对象属性。相反,当对象从集合中插入/删除时,您必须添加/删除观察者。

可以在此处找到说明和示例项目: https://web.archive.org/web/20120319115245/http://homepage.mac.com/mmalc/CocoaExamples/controllers.html
(请参阅“观察集合与观察集合中对象的属性不同”部分)

更新:
链接损坏了 - 我将其更改为 archive.org 快照。

AFAIK there is no built-in way to observe collection object properties with a single line of code. Instead you have to add/remove observers when the object is inserted/removed from your collection.

An explanation and a sample project can be found over here: https://web.archive.org/web/20120319115245/http://homepage.mac.com/mmalc/CocoaExamples/controllers.html
(See the "Observing a collection is not the same as observing the properties of the objects in a collection" section)

Update:
The Link broke - I changed it to an archive.org snapshot.

请持续率性 2024-12-26 02:26:17

答案有点晚了,但也许对用谷歌搜索这个的人有用。

您可以使用谓词 @"parent == %@", child 为实体子级设置一个 NSFetchedResultsController,然后将您的控制器作为委托添加到该 fetchedResultController。当子项的任何属性发生更改以及添加它们时等时,将调用委托。
下面是示例代码。我还添加了一个排序描述符,用于按子级的名称对子级进行排序,

...
NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Child"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"parent = %@", parent];
self.fetchResultsController.fetchRequest.predicate = predicate;

self.fetchResultsController = [[NSFetchedResultsController alloc] 
     initWithFetchRequest:fetchRequest managedObjectContext:context 
     sectionNameKeyPath:nil cacheName:nil];

self.fetchResultsController.delegate = self;
...

然后您实现委托方法

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath {

以及实现所需的任何其他委托方法(文档对此有一个非常好的代码片段)

A bit of a late answer, but maybe it will be useful to someone who googles this.

You can setup an NSFetchedResultsController for the entity child with the predicate @"parent == %@", childand then add your controller as a delegate to that fetchedResultController. The delegate will be called when any of the properties of the child changes, as well as when they are added etc.
An example code follows. I have also added a sort descriptor to sort the children by their name to the

...
NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Child"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"parent = %@", parent];
self.fetchResultsController.fetchRequest.predicate = predicate;

self.fetchResultsController = [[NSFetchedResultsController alloc] 
     initWithFetchRequest:fetchRequest managedObjectContext:context 
     sectionNameKeyPath:nil cacheName:nil];

self.fetchResultsController.delegate = self;
...

Then you implement the delegate method

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath {

And any other delegate method you need for your implementation (the documentation has a very good code snippet for this

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文