blue
blue

Reputation: 7375

Swift: Updated and got error: "cannot invoke '!=' with argument list of type.."

Everything was fine in Xcode beta 5 but now in full fledged Xcode I'm getting 2 similar errors in my App Delegate:

  1. "cannot invoke '!=' with argument list of type '(NSManagedObjectContext, NilLiteralConvertible')"

  2. "cannot invoke '!=' with argument list of type '(NSPersistentStoreCoordinator, NilLiteralConvertible')"

I tried replacing the != with !== and I get a different error. I don't see what the problem is with !=. The code:

func saveContext () {
        var error: NSError? = nil
        let managedObjectContext = self.managedObjectContext
        if managedObjectContext != nil { //THIS LINE
            if managedObjectContext.hasChanges && !managedObjectContext.save(&error) {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate.
                //println("Unresolved error \(error), \(error.userInfo)")
                abort()
            }
        }
    }

    // #pragma mark - Core Data stack

    // Returns the managed object context for the application.
    // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
    var managedObjectContext: NSManagedObjectContext {
        if _managedObjectContext !== nil {
            let coordinator = self.persistentStoreCoordinator
            if coordinator != nil { //THIS LINE
                _managedObjectContext = NSManagedObjectContext()
                _managedObjectContext!.persistentStoreCoordinator = coordinator
            }
        }
        return _managedObjectContext!
    }
    var _managedObjectContext: NSManagedObjectContext? = nil

I have a new error: "'NSManagedObjectContext?' does not have a member named 'hasChanges'" In this code:

func saveContext () {
        var error: NSError? = nil
        let managedObjectContext = self.managedObjectContext
        if managedObjectContext != nil {
            if managedObjectContext.hasChanges && !managedObjectContext.save(&error) { //This line
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate.
                //println("Unresolved error \(error), \(error.userInfo)")
                abort()
            }
        }
    }

Upvotes: 3

Views: 7509

Answers (2)

erdekhayser
erdekhayser

Reputation: 6657

The reason for this is because NSManagedObjectContext, and probably NSPersistentStoreCoordinator, do not conform to the Equatable protocol. In order to use == and !=, an object needs to conform to this protocol.

=== and !== do not check equality in that sense. These check to see if two objects are in fact the *same object`. Not with similar values. They both point to the same object in memory.

You are able to check this on the two noted types because they are objects. This should work fine for your situation.

About your second issue, your code should look like this:

func saveContext () {
    var error: NSError? = nil
    let managedObjectContext = self.managedObjectContext
    if let moc = managedObjectContext {
        if moc.hasChanges && !moc.save(&error) { //This line
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate.
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }
    }
}

The difference here is if let moc = managedObjectContext: if managedObjectContext is not nil, the value is stored in the constant moc. Otherwise, whatever is inside does not get executed. You can read more about optionals here.

Upvotes: 3

iluvcapra
iluvcapra

Reputation: 9464

self.managedObjectContext is here typed as an NSManagedObjectContext, not an NSManagedObjectContext?.

You can't compare a var to nil unless it's of type Optional<>, implements Equatable, or is nil itself.

Upvotes: 1

Related Questions