我有一个带有自定义类的 Parent 实体,该类具有名为 DerivedProperty 的 transient 派生(只读)属性。
DerivedProperty 的值取决于 Parent.IndependentProperty1 的值,因此每当 IndependentProperty1 更改时,DerivedProperty 的值 会改变。但是,Parent 与 Child(称为 children)具有一对多关系,并且 DerivedProperty 也依赖于IndependentProperty2 在所有 Parent 的 Child 对象中的值。
因此,每当 Parent 的 IndependentProperty1 或任何 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 来观察一对多关系的 IndependentProperty1 和 IndependentProperty2 但我似乎无法让它正常工作。如果派生属性不依赖于一对多关系,那么我确定我可以只使用 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/
我主要使用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
我希望我的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
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个具有一些属性的模型: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
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
这里有一个很好的答案解释了如何在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返回它复制的字节数,但是当我还没有下
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在尝试使用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_