如何告诉(托管)对象通知其 KVO:其属性之一需要重新缓存?

发布于 2024-07-29 06:29:42 字数 327 浏览 4 评论 0原文

当我们的对象具有基于其他属性生成的属性时,通常我们会实现 +keyPathsForValuesAffecting{PropertyName} 类方法。

我想要做的事情基本上与 NSManagedObject 上的属性相同,但遍历关系。

我的模型很简单; 我有两个实体,应用程序和版本(我正在创建一个应用程序生成应用程序)。 当应用程序的属性更改时,因为我实现了上面的方法,所以 -appcast 字符串发生更改,并且所有绑定都会相应更新。

但是,当任何特定应用程序版本(一对多关系)上的任何属性发生更改时,-appcast 属性不会正确生成。 我可以修复/解决方法吗?

When we have an object who has a property that's generated based on other properties, usually we implement the +keyPathsForValuesAffecting{PropertyName} class method.

What I'm trying to do is basically the same thing for a property on my NSManagedObject, but traversing a relationship.

My model is simple; I have two Entities, App and Version (I'm creating an appcast-generating app). When the App's properties are changed, because I implemented the method above, the -appcast string is changed, and all bindings are updated appropriately.

However, when any properties on any of a specific App's Versions (to-many relationship) change, the -appcast property is not generated appropriately. I can haz fix/workaround?

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

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

发布评论

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

评论(1

谎言月老 2024-08-05 06:29:42

这个答案有点晚了,但我认为这是一种常见的情况,而且答案肯定不是显而易见的。

我通常会观察 ManagedObjectContext 的更改,然后检查更改的对象是否是我想要查找的对象。 因此,在您的 NSManagedObject 子类中:

// We need to register for the notification in both awakeFromFetch
// AND awakeFromInsert, since either one could be called, depending on
// if the object was previously-created or not
- (void)awakeFromFetch {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)awakeFromInsert {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)managedObjectContextDidChange:(NSNotification *)notification {
    // Get a set containing ALL objects which have been changed
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];

    NSSet *changedObjects = [insertedObjects setByAddingObjectsFromSet:updatedObjects];
    changedObjects = [changedObjects setByAddingObjectsFromSet:deletedObjects];

    if ([changedObjects intersectsSet:[self versions]]) {
        [self willChangeValueForKey:@"appCast"];
        [self didChangeValueForKey:@"appCast"];
    }
}

从性能角度来看,这当然不理想,因为每次对象图中的任何内容发生变化时都会触发此通知,但我发现它是最重要的实现这一点的简单方法。

This is a bit of a late answer, but I think it's a common situation, and the answer definitely isn't readily-apparent.

I generally watch for the managedObjectContext to change and then check if the any of the changed objects are ones that I want to look out for. So, in your NSManagedObject subclass:

// We need to register for the notification in both awakeFromFetch
// AND awakeFromInsert, since either one could be called, depending on
// if the object was previously-created or not
- (void)awakeFromFetch {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)awakeFromInsert {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]];
}

- (void)managedObjectContextDidChange:(NSNotification *)notification {
    // Get a set containing ALL objects which have been changed
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];

    NSSet *changedObjects = [insertedObjects setByAddingObjectsFromSet:updatedObjects];
    changedObjects = [changedObjects setByAddingObjectsFromSet:deletedObjects];

    if ([changedObjects intersectsSet:[self versions]]) {
        [self willChangeValueForKey:@"appCast"];
        [self didChangeValueForKey:@"appCast"];
    }
}

This is certainly not ideal from a performance perspective, since this notification is going to fire every time anything in your object graph changes, but I've found it to be the most straightforward way to accomplish this.

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