Coder
Coder

Reputation: 1681

if let nil in swift 2.0 is not working as expected

"if let nil" check is not working in Swift 2.0, but was working fine in Swift 1.2.

In the below code, "fetchNumbersFromCoreDataDB" function returns nil. In getDatabaseDate function, I have a condition "if let date = dbDate". This condition ideally should fail and go to else block. But in Swift 2.0, it is going inside the if block. In Swift 1.2, same code is going to else block. I am confused here. What is the difference here?

 func getDatabaseDate() {
        let dbDate : NSDate? = ((self.fetchNumbersFromCoreDataDB(“123456”) as DBNumbers!).dbDate)
        if let date = dbDate {
           print(“\(date)”)
        }
        else {
            print(“No Date”)
        }
    }


 func fetchNumbersFromCoreDataDB(Number:String) -> DBNumbers? {
      var numArray = coreDataInterface.fetchAllObjectsFromEntity(info, withAttributeValues: [“No” : Number]) as! [DBNumbers]
      return numArray.count>0 ? numArray[0] : nil
 }

Note: "dbDate" is NSDate type in Coredata table

Upvotes: 1

Views: 269

Answers (1)

Tommy
Tommy

Reputation: 100632

The let dbDate line is very oddly constructed and would raise an exception if your fetchNumbersFromCoreDataDB were returning nil. Therefore your fetchNumbersFromCoreDataDB is not returning nil.

Your line:

let dbDate : NSDate? = ((self.fetchNumbersFromCoreDataDB(“123456”) as DBNumbers!).dbDate)

as DBNumbers! says to convert from DBNumbers? to DBNumbers!. So you've got an optional that is implicitly unwrapped.

Hence .dbDate says to unwrap the return result of fetchNumbersFromCoreDataDB and get the dbDate property from it. Had fetchNumbersFromCoreDataDB returned nil, the attempt to unwrap would raise an exception.

What you probably wanted was:

let dbDate = self.fetchNumbersFromCoreDataDB(“123456”)?.dbDate

Which says "if the optional returned by fetchNumbersFromCoreDataDB is not nil then get its dbDate property; otherwise get nil".

If you really need to convince yourself empirically, open a playground and try this:

class DBNumbers {
    var dbDate: NSDate?
}

func fetchNumbersFromCoreDataDB(Number:String) -> DBNumbers? {
    return nil
}

let dbDate : NSDate? = (fetchNumbersFromCoreDataDB("123456") as DBNumbers!).dbDate

You'll get an EXC_BAD_INSTRUCTION on the last line.

Upvotes: 1

Related Questions