60

I have encountered this keyword in various occasions. I kind of know what it's suppose to do. But I really want a better understanding of it.

What I noticed about @NSManaged - based not on documentation, but through repeated use:

  1. It magically replaces key value coding.
  2. It is roughly equivalent to @dynamic in Objective-C (which I don't know much about)
  3. I need it to subclass PFObject from the Parse SDK. It normally uses KVC to read/write values from/to the backend.
  4. Prefixing any variable with @NSManaged will shut the compiler up when I don't initialize within the initializer.

The formal definition (in the Core Data Apple Docs):

Core Data provides the underlying storage and implementation of properties in subclasses of the NSManagedObject class. Add the @NSManaged attribute before each property definition in your managed object subclass that corresponds to an attribute or relationship in your Core Data model. Like the @dynamic attribute in Objective-C, the @NSManaged attribute informs the Swift compiler that the storage and implementation of a property will be provided at runtime. However, unlike @dynamic, the @NSManaged attribute is available only for Core Data support.

What I got from that:

Variables with @NSManaged shall be exempt from compile time checks for something.

I've read the formal documentation and various other SO questions regarding this matter:

@synthesize vs @dynamic, what are the differences?

What is common case for @dynamic usage?

I instinctively recognize some scenarios where I should use it. I partially know what it does. But what I seek is purer understanding of what it does.

Further Observations:

A PFObject in the Parse SDK relies on Key Value Coding to access its values. The PFObject provides the following accessors:

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 

To my understanding, @NSManaged magically understands that the variable I've declared automatically uses the above accessors to get and set. I'd like to know how it does that (if what I understand is true), and whatever else it does.

Community
  • 1
  • 1
Kelvin Lau
  • 6,373
  • 6
  • 34
  • 57
  • Did you ever find out how the behaviour you observed (in Further Observations) was achieved? How does @NSManaged use the correct accessors? – Jason Feb 08 '16 at 21:53
  • 2
    the @NSManaged attribute is available only for Core Data support is not entirely right. You need to also use it for CoreAnimation swift variables that you want to animate on: http://stackoverflow.com/questions/24150243/are-needsdisplayforkey-actionforkey-overrides-working-correctly – ambientlight Aug 28 '16 at 14:26

3 Answers3

57

Yes, it kinda really acts like @dynamic -- technically it might be identical even. Semantically there is a slight difference:

@dynamic says 'compiler, don't check if my properties are also implemented. There might be no code you can see but I guarantee it will work at runtime'

@NSManaged now says 'compiler, don't check those properties as I have Core Data to take care of the implementation - it will be there at runtime'

so you could even say: @NSManaged is syntactic sugar that is a more narrow version of dynamic :)


https://github.com/KyoheiG3/DynamicBlurView/issues/2
here someone even used @NSManaged without CD because he wanted the @dynamic behaviour

Aderstedt
  • 6,301
  • 5
  • 28
  • 44
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • I want to dive a bit deeper into the matter - How does the compiler normally know how the property is implemented, and how does `@NSManaged` make the compiler defer this responsibility elsewhere? Is it similar to `super` call when overriding a method? Is `@NSManaged` telling the compiler: "Get the implementation details from the superclass"? – Kelvin Lau Jul 11 '15 at 13:29
  • normally, on compilation the machine code for method (or property) must be there -- thats what the compiler checks. BUT the objC/swift runtime supports adding machine code at runtime ... then somebody has to add the code just in time :) with NSManaged, coreData does just that for you. The code is NOT in the superclass but generated on the fly – Daij-Djan Jul 12 '15 at 11:33
  • @KelvinLau do you still have questions here? – Daij-Djan Nov 02 '15 at 18:05
  • 2
    @Daij-Djan Actually, `@NSManaged` seems to be really identically with `@dynamic` from the runtime's perspective. http://cocoaexposed.com/2015/nsmanaged-vs-dynamic-in-swift/ – Rad'Val Nov 07 '15 at 22:54
  • Can you see [here](https://stackoverflow.com/questions/53891194/what-are-the-functional-differences-between-coredatas-codegen-manual-none-cr)? I tested the following: "dumping something like `@NSManaged public var name: String?` straight into an existing `NSManagedObject` subclass. Seemingly it's not allowed. I tried to do `entity.name = "John"` but I get unrecognized selector error. I believe that's reasonable ie without using the Core Data Model Editor the setter/getter accessor methods are not created." Is that right? or using Core Data Model Editor is not necessary to generate accessors? – mfaani Dec 26 '18 at 13:40
  • Yes. Every managed property needs to be defined in the schema – Daij-Djan Dec 26 '18 at 13:42
  • Thanks. I placed a 100 bounty on that question, so if you like to answer it please do so. The main other question mentioned there is: "how does me changing `NSDate` to `Date` or optional to non-optional not break the mappings between my NSManagedObject class and my object graph all while changing an `NSDate` property to `String` does break!! Does this have something to do with things that have guaranteed casting between Swift and Objective-C ie things that can be casted through `as` — without `?` or `!`?" – mfaani Dec 29 '18 at 13:18
4

In the apple docs, for Custom Managed Object Class, they quote properties example like... enter image description here To me it seems there is no difference, I have used @dynamic in objective C, it seems @NSManaged is the replacement in Swift.

BangOperator
  • 4,377
  • 2
  • 24
  • 38
0

Above mentioned answers are right. Here is my understanding.

@NSManaged indicates that the variables will get some values when we run the app. Coredata automatically creates getter and setter for such props. It silences the compiler for warnings.

NSmanaged is subclass of NSObject. @NSManaged means extra code will be given to these props at runtime. It tracks the changes made to those properties.

iPhoneDeveloper
  • 958
  • 1
  • 14
  • 23