14

I've read many of the SO questions on NSManagedObject, the Apple docs, and more, but I still don't really get what subclassing NSManagedObject is for - what role does it play?

In the Apple docs it talks about how I can't override a bunch of methods, shouldn't use custom instance variables, blah and blah (I don't understand some of it yet), and so forth - so what can I do with NSManagedObject? What are the restrictions, must-follow guidelines, and what aren't restrictions?

I'm trying to make a little box drawing program to learn Core Data, and I'm thinking of adding "draw" methods to a subclass of NSManagedObject so that a view can just tell them to draw for itself - is this permitted?

So, my question in one sentence would be, what's the "real" difference between subclassing NSManagedObject and any other class - what does Core Data do with it?

If this is too broad, I'll try to narrow my question down or something.

Vervious
  • 5,559
  • 3
  • 38
  • 57

1 Answers1

25

I still don't really get what subclassing NSManagedObject is for - what role does it play?

Convenience for the developer - in terms of CodeSense, shorter syntax, and some compile-time checks that help thwart misspellings of keys.

so what can I do with NSManagedObject? What are the restrictions, must-follow guidelines, and what aren't restrictions?

The UI built into Xcode will make the NSManagedObject subclasses for you - you really don't need to do it by hand - but, basically, they are just NSManagedObjects with some properties tacked on. Instead of using @synthesize or such, you use @dynamic and Apple takes care of the rest for you - hooking up those properties to getters/setters which mimic what you would normally do with a "bare" NSManagedObject.

I'm trying to make a little box drawing program to learn Core Data, and I'm thinking of adding "draw" methods to a subclass of NSManagedObject so that a view can just tell them to draw for itself - is this permitted?

You could.... but I wouldn't. This sounds like bad design - try to keep your Model and Controllers separate.

Model objects shouldn't contain business logic / drawing code. Use the model simply as the "state" of your application. Make something else responsible for the drawing. Plus, while I can't say this with absolute authority, I believe there is some overhead if you're dealing with updating / retrieving info from an NSManagedObject.

(Basically, it's like dealing with an NSDictionary... sorta. It's less efficient to grab items out of a dictionary than it is to access an ivar.)

For an app that does things like drawing - you'll probably want to avoid that overhead by making a structure for your in-memory things, and possibly a second, similar structure for persistence/serialization (like to CoreData).

So, my question in one sentence would be, what's the "real" difference between subclassing NSManagedObject and any other class - what does Core Data do with it?

I would say - don't subclass NSManagedObject by hand at all - use what Xcode gives you. If you want more (other than maybe a custom constructor) then you're probably barking up the wrong tree.

EDIT:

I think there might have been some confusion about what I meant when I said "don't subclass NSManagedObject by hand at all"

To elaborate, and incorporate one of the responses:

Start with the data model designer in Xcode, create your models, and use the following menu option:

enter image description here

Then, you could modify the generated class to include custom:

  • Constructors
  • Data Conversion Methods
  • Validation
  • Formatting
  • Sort Descriptors
  • Filters

If your use case doesn't fit in that list, you should really seriously think about putting it somewhere else (as in your example with the "Draw" method).

All of those things mentioned above could be tacked on to an NSManagedObject subclass which was created for us by Xcode (we didn't create "by hand") - and they all revolve around dealing with the data directly (formats / conversions / etc) and/or around pulling the data out of Core Data (filters / sorting).

They don't add iVars, they don't perform any complicated operations outside of the scope of data storage and retrieval.

Steve
  • 31,144
  • 19
  • 99
  • 122
  • 2
    Most of this answer is good, but I disagree with "don't subclass NSManagedObject by hand at all" -- I have yet to have a Core Data project that didn't eventually subclass NSManagedObject. It's very common to handle transient variables and data conversion. It also provides better type safety. In practice, I almost always wind up creating a subclass for every entity just for consistency. It gets confusing when some are subclassed and some are not. – Rob Napier Oct 30 '11 at 20:37
  • 1
    I'll add to that: (1) custom validation, (2) factory methods, (3) string formatting, (4) class methods for associated sort descriptors and filter predicates. – paulmelnikow Oct 30 '11 at 21:57
  • 1
    @RobNapier - Oh, absolutely - What I meant by "by hand" was "If you are creating a Core Data entity, and you're using it to store things in Core Data, and Xcode would/could create the start of your entity for you - then that's an appropriate place for a subclass" - As I mentioned, Constructors are definitely something I could see adding - data translation methods as well as you mentioned are fine - but don't just make everything that would have been an NSObject subclass an NSManagedObject subclass for no reason (as in the OP's example about the boxes). – Steve Oct 30 '11 at 22:53
  • I don't know that I'd agree on no business logic; it makes much more sense to make your models "smarter" than cluttering your controllers. Agree on the no view stuff, though. – wkhatch Dec 30 '11 at 02:17
  • 1
    @wkhatch - I didn't say the business logic should go in your `UIViewController`s. Typical scenario is three tier - UI | Business Logic | Data Access. – Steve Dec 30 '11 at 04:46
  • In general, I would agree about model objects not knowing about drawing. However, I would disagree about it in this specific case. In a drawing app, drawing *is what is being modelled*, so the model layer should know about drawing! See Apple's Sketch sample app for an example of this. – Ben Lings Oct 24 '12 at 09:28
  • @BenLings, Models knowing information about geometries and knowing how to draw themselves using Quarts/Core Graphics are two entirely different things. I've been quite successful building several drawing-type applications, and I can tell you that the "model" used to save/load data to/from has no idea how to work with Quartz (or WPF, or GDI, or Android's drawing routines, etc). Ex: If you were building a city traffic planning application you'd doubtless need to know the radius of a highway exit ramp in the model - that doesn't mean the model needs to be responsible for drawing that as well. – Steve Oct 25 '12 at 21:43
  • @Steve - See the responses to http://stackoverflow.com/questions/336039/how-are-the-classes-in-the-sketch-example-appkit-application-separated-into-mode for discussion on the Sketch sample app – Ben Lings Oct 26 '12 at 12:47
  • 1
    @BenLings, As with anything (naming conventions, design patterns, etc) people will have different opinions. Also, what's appropriate for a sample application and what's appropriate for a real-world application are two different things. Having built several cross-platform retail graphics-based applications similar to that sample program, I'm expressing my opinion - and that's all it is - my opinion. You're free to disagree. However, it is my opinion that the model isn't a view - and shouldn't have rendering logic built into it. I've tried it both ways, and this is what has worked best for me. – Steve Oct 26 '12 at 23:13