3

In Xcode 6.1 and with the blog post about Failable Initializers on the Swift Blog, Apple has assigned to self in a failable initializer.

The Int (init(fromString:)) example on the blog post compiles fine when copied into my project with an assignment to self, but trying this with a custom class in my own code results in the usual error "Cannot assign to 'self' in a method".

extension Contact {
    public convenience init?(context: NSManagedObjectContext = DataStore.managedObjectContext) {
        if let userId = User.loggedInUserId(context) {
            let contact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: context) as Contact

            self = contact
        } else {
            return nil
        }
    }
}

(Contact is a subclass of NSManagedObject)

Is there anything I am missing with failable initializers?

Damien Pontifex
  • 1,222
  • 1
  • 15
  • 27

2 Answers2

4

Assigning to self is for value types only, struct and enum.

In your case you should do like this:

public convenience init?(context: NSManagedObjectContext) {
    let entity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: context);
    self.init(entity: entity!, insertIntoManagedObjectContext: context)

    if  User.loggedInUserId(context)  == nil {
        context.deleteObject(self)
        return nil
    }
}

You must call self.init(..) unconditionally, because, it's a rule for convenience initializer. If the condition is false, deleteObject(self) and return nil. Hmm... I think you should not use failable initializers for this.

rintaro
  • 51,423
  • 14
  • 131
  • 139
  • Wouldn't have to delete except it seems you have to call self.init(entity before returning nil. Can't do the checks before calling the designated initialiser. – Damien Pontifex Oct 21 '14 at 01:44
0

A convenience initializer must call a designated initializer from the same class. Instead of assigning to self, can you create a designated initializer that takes and copies a Contact instance?

Nate Cook
  • 92,417
  • 32
  • 217
  • 178