1
\$\begingroup\$

I have a situation where I have to use protocol to be conformed by NSManagedObject which has relationships with other entities.

My protocol is like:

protocol Account {
  var accountId: String { get }
  var isValidAccount: Bool { get }
}

Here is that entity:

class AccountMO: NSManagedObject {
  @NSManaged var uid: String!
  @NSManaged var anotherEntity: AnotherEntity?

  private (set) var storedMOC: NSManagedObjectContext!
  override var managedObjectContext: NSManagedObjectContext? {
    return storedMOC
  }

  override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
    super.init(entity: entity, insertInto: context)
    storedMOC = context!
  }
  init(moc:NSManagedObjectContext) {
    //I'm using this method to init AccountMO
    let mEntity = NSEntityDescription.entity(forEntityName: "Account", in: moc)
    super.init(entity: mEntity!, insertInto: moc)
  }
  func addAnotherEntity() {
    //this method creates AnotherEntity
    //and this method will be called after particular event has happened
  }
}

Extension which is conforming protocol:

extension AccountMO: Account {

  var accountId: String {
    return uid!
  }
  var isValidAccount: Bool {
    return anotherEntity != nil
  }
}

Whenever I want Account properties, I uses DB interface to fetch and return AccountMO as:

class DBInterface {
  //initialization methods
  var mainThreadMOC: NSManagedObjectContext?

  func createNewAccount(uid: String) {
    //create and save account to database
  }
  func getAccount() -> Account {
    //this method abstracts database implementations from outside classes
   //in future if I wanted to replace core-data by another database, I've to change this method only
    let privMOC = privateMOC()//this is child of mainThreadMOC
    let accountMO = fetchAccountEntity(moc: privMOC)
    return accountMO as Account
  }
}

This works fine!

But what I felt is storedMOC in AccountMO is something odd man out! If I don't store MOC in AccountMO object, then it crashes on

return anotherEntity != nil

this line.
Apparently this is caused because AccountMO looses it's managedObjectContext once returned from getAccount() method.

So, to prevent AccountMO from losing it's managedObjectContext I've added that extra property to it.

Please feel free to tear this implementation down if needed!

\$\endgroup\$
1
\$\begingroup\$

NSManagedObjects already have a property for their current context. It is weak however, which is usually ok for most cases because you would retain the context in the class which is using the objects or in the fetch controller that fetched them. If you are using a child context then you need to be sure to retain that otherwise the object fetched from it will lose it.

More info here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.