简体   繁体   中英

CoreData - Benefits of NSManagedObject Subclass

I am trying to insert into CoreData without creating a subclass of NSManagedObject. but my app crashes with NSManagedObject setValue:forUndefinedKey "name" in Category.

    let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let entitiyDesc = NSEntityDescription()
    entitiyDesc.name = "Category"
    guard let data = model.data else { return }
    for d in data {
        let managedObject = NSManagedObject.init(entity: entitiyDesc, insertIntoManagedObjectContext: managedObjectContext)
        managedObject.setValue(d.name, forKey: "name")
    }
    try! managedObjectContext.save()

What are the benefits of subclassing NSManagedObjects

There is nothing wrong with the way you are using Core Data. Generally you start wanting to subclass when:

  • You want convenience methods on your NSManagedObject
  • You are using transient values that are not in the model at all
  • Want to react to the creation or insertion of an NSManagedObject
  • Want to present an easier to use object to your UI developers
  • Want to avoid using "magic strings" when accessing properties

and I am sure there are more in that list.

You never need to subclass an NSManagedObject but in many situations it does make your code cleaner and easier to maintain.

A couple of comments on your code:

  • NSEntityDescription and NSManagedObject should not be created that way. You should be using the convenience method NSEntityDescription.insertNewObjectForEntityForName(_:) instead
  • Using a forced try like that is very bad for error handling. You are FAR better off using a do/catch so that you can interrogate the error completely. This is especially important with Core Data that will send you sub errors.
  • Accessing the NSManagedObjectContext through the AppDelegate like that is a poor design (yes I know its in the Apple template). It is far better to use dependency injection as discussed in the Core Data Programming Guide and avoid the tight coupling that is inherent with accessing the AppDelegate

Subclassing NSManagedObject honestly makes your life easier as a developer.

  • No need to hassle with setValue:forUndefinedKey .
  • Easy initializer for every entity
  • Easier to manage your entities with auto generated models by Xcode

You should check out the official documentation or this tutorial to get started.

Marcus Zarra's answer is 100% correct, but I would just like to stress that considering the risks of "undefined key" and type-casting errors, and the debugging cost while mentally remembering which entities have which attribute keys, to subclass or not should not even be a choice .

Strongly-typing your NSManagedObject s (ie by subclassing) also opens up a whole lot of compile-time checks and utility, especially in Swift.

If you are new to Core Data let me introduce you to the library I wrote, CoreStore , which was heavily designed around Swift's type-safety:

  • Generics allow for zero type-casting
  • Entity-aware NSFetchedResultsController -like observers
  • Protocol-based data importing

You also get powerful features such as transactions, progressive migrations, and more. It's like Core Data on training wheels; if there's a bad practice in Core Data, CoreStore will most likely not let you write that code in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM