jjzjj

ios - 核心数据 : Emitting KVO notifications for transient, 派生属性

coder 2024-01-17 原文

我有一个带有自定义类的 Parent 实体,该类具有名为 DerivedProperty 的 transient 派生(只读)属性。

DerivedProperty 的值取决于 Parent.IndependentProperty1 的值,因此每当 IndependentProperty1 更改时,DerivedProperty 的值 会改变。但是,ParentChild(称为 children)具有一对多关系,并且 DerivedProperty 也依赖于IndependentProperty2 在所有 ParentChild 对象中的值。

因此,每当 ParentIndependentProperty1 或任何 Child 对象的 IndependentProperty2 发生变化时,我想通知所有观察者 DerivedProperty 也已更改。

到目前为止,我已经得到了以下代码。唯一的问题是没有为 DerivedProperty 发出 KVO 通知,因为如果我尝试在 objectContextDidChange: 中执行此操作,那么代码将以循环结束。

- (void) awakeFromInsert
{
    [super awakeFromInsert];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectContextDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.managedObjectContext];
}


- (void) awakeFromFetch
{
    [super awakeFromFetch];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectContextDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.managedObjectContext];
}

- (void) objectContextDidChange: (NSNotification *) notification
{
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];

    if ([updatedObjects containsObject:self] || [updatedObjects intersectsSet:self.children])
    {
        //clear caches
        _derivedProperty  = nil;
    }
}

- (void) didTurnIntoFault
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (NSString *) DerivedProperty
{
    if (_derivedProperty == nil)
    {
        _derivedProperty  = [self someExpensiveCalculation];
    }
    return _derivedProperty  ;
}

我确定我需要彻底重新考虑我的方法。我已经尝试使用 KVO 来观察一对多关系的 IndependentProperty1IndependentProperty2 但我似乎无法让它正常工作。如果派生属性不依赖于一对多关系,那么我确定我可以只使用 keyPathsForValuesAffectingValueForKey: 但当然这在一对多关系中不起作用。

如何让 KVO 通知与依赖于一对多关系的 Core Data transient 派生属性一起使用?

最佳答案

首先,您在 -objectContextDidChange: 方法中访问 DerivedProperty 的 ivar,并使 KVO 通知短路。您真的应该在内部将该属性重新实现为读/写并使用生成器访问器。

其次,NSManagedObject 的子类默认关闭自动 KVO。这是核心数据架构的一部分。因此,如果您不打算使用访问器,您可能希望自己触发通知:

- (void) objectContextDidChange: (NSNotification *) notification
{
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];

    if ([updatedObjects containsObject:self] || [updatedObjects intersectsSet:self.children]) {
        //clear caches
        [self willChangeValueForKey:@"derivedProperty"];
        _derivedProperty  = nil;
        [self didChangeValueForKey:@"derivedProperty"];
    }
}

注意事项

在这种情况下,OP 使用 transient 属性 AND 直接访问该属性的 iVar。这有效地创建了两个 iVar,一个由 Core Data 维护,另一个由 OP 代码维护。这引起了碰撞。

如果您使用的是 transient 属性,建议您按照建议将计算转移到另一种方法,并将访问器留给 Core Data。

关于ios - 核心数据 : Emitting KVO notifications for transient, 派生属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16738126/

有关ios - 核心数据 : Emitting KVO notifications for transient, 派生属性的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  5. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  6. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  9. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  10. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

随机推荐