@NSManaged是什么?

61

我在各种场合都遇到了这个关键字。我有点知道它应该做什么。但我真的想更好地理解它。

根据重复使用的经验而非文档,我注意到了 @NSManaged

  1. 它神奇地替换了键值编码。
  2. 它与 Objective-C 中的 @dynamic 大致等价(而我对此并不了解太多)
  3. 我需要它来从 Parse SDK 继承 PFObject。通常,它使用 KVC 从后端读取/写入值。
  4. 在变量前加上任何前缀,只要有 @NSManaged,当我没有在初始化器中初始化时,编译器就会闭嘴。

正式定义(Core Data Apple 文档中):

Core Data 为 NSManagedObject 类的子类提供了属性的底层存储和实现。在托管对象子类中,为每个属性定义之前添加 @NSManaged 属性,该属性对应于 Core Data 模型中的属性或关系。与 Objective-C 中的 @dynamic 属性一样,@NSManaged 属性告诉 Swift 编译器属性的存储和实现将在运行时提供。但是,与 @dynamic 不同,@NSManaged 属性仅适用于 Core Data 支持。

我从中得到的:

带有 @NSManaged 的变量应该从编译时检查 某些 东西中豁免出来。

我已经阅读了正式文档和其他各种关于此问题的 SO 问题:

@synthesize vs @dynamic, what are the differences?

What is common case for @dynamic usage?

我本能地认识到了一些我应该使用它的情况。我部分知道它的作用。但我所追求的是更纯粹的理解。

进一步观察:

Parse SDK 中的 PFObject 依赖于键值编码来访问其值。 PFObject 提供以下访问器:

objectForKey:

let score = results.objectForKey("descriptionOfResult") 
//returns the descriptionOfResult value from the results object

setObject:forKey:

:设置键值对。
results.setObject("The results for a physics exam", forKey: "descriptionOfResult") 
//sets the value of descriptionOfResult 

据我理解,@NSManaged神奇地理解到我声明的变量自动使用上面的访问器来getset。如果我所理解的是正确的,我想知道它是如何做到这一点的,以及它还能做什么。


你是否曾经弄清楚了在“进一步观察”中所观察到的行为是如何实现的?@NSManaged 如何使用正确的访问器? - Jason
2
“@NSManaged”属性仅适用于Core Data支持并不完全正确。您还需要将其用于要在CoreAnimation Swift变量上执行动画的情况:https://dev59.com/aYDba4cB1Zd3GeqPFIS1 - ambientlight
3个回答

57

是的,@NSManaged在技术上可能与@dynamic完全相同,但从语义上略有不同:

@dynamic表示“编译器,请不要检查我的属性是否也已实现。 可能没有你能看到的代码,但我保证它在运行时可以正常工作”

@NSManaged现在表示“编译器,请不要检查这些属性,因为我有Core Data来处理实现 - 它将在运行时出现”

所以你甚至可以说:@NSManaged是一个更窄版的dynamic的语法糖 :)


https://github.com/KyoheiG3/DynamicBlurView/issues/2
在这里,有人甚至在没有CD的情况下使用了@NSManaged,因为他想要@dynamic的行为。


我想深入了解一下这个问题——编译器通常如何知道属性是如何实现的,以及@NSManaged如何使编译器将这个责任委托给其他地方?这是否类似于重写方法时调用super@NSManaged是否告诉编译器:“从超类获取实现细节”? - Kelvin Lau
通常,在编译时,方法(或属性)的机器码必须存在 - 这是编译器检查的内容。但是,objC/swift运行时支持在运行时添加机器码...然后有人必须即时添加代码 :) 使用NSManaged,coreData会为您完成这项工作。代码不在超类中,而是动态生成的。 - Daij-Djan
@KelvinLau你还有问题吗? - Daij-Djan
2
@Daij-Djan 实际上,从运行时的角度来看,@NSManaged 似乎与 @dynamic 完全相同。http://cocoaexposed.com/2015/nsmanaged-vs-dynamic-in-swift/ - Rad'Val
你能在 这里 看到吗?我测试了以下内容:“将类似 @NSManaged public var name: String? 的东西直接放入现有的 NSManagedObject 子类中。看起来是不允许的。我试图执行 entity.name = "John",但出现了未识别选择器错误。我认为这是合理的,即如果不使用 Core Data 模型编辑器,则不会创建设置器/获取器访问方法。” 这正确吗?或者说使用 Core Data 模型编辑器不是生成访问器的必要条件? - mfaani
显示剩余2条评论

4
苹果文档中,对于自定义托管对象类,他们引用了属性示例,例如... enter image description here 对我来说似乎没有区别,我已经在Objective-C中使用了@dynamic,它似乎在Swift中被@NSManaged替代。

0
以上提到的答案是正确的。这是我的理解。
@NSManaged 表示当我们运行应用程序时,变量将获得一些值。Coredata 会自动为这些属性创建 getter 和 setter。它可以消除编译器警告。
NSmanaged 是 NSObject 的子类。 @NSManaged 意味着在运行时将为这些属性提供额外的代码。 它跟踪对这些属性所做的更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接