Optional wrapping in Swift, why does Swift add the “Optional” to the string

a 夏天 提交于 2019-12-08 09:37:38

问题


I'm saving an array into a model, when saving the data is not wrapped with Optional (...) however when the data is being read I get the Optional(...) wrapping around it. Appreciate your help and patience as I'm new to Swift.

This is the println when adding the values to the model:

saveOperativesInModel: Test Name

This is the println when reading the values back from the model:

getOperativesFromModel: Optional(Test Name)

Why does Swift add the "Optional(xxx)" to the String?

This is the reduced code:

func saveOperativesInModel() {


    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext!
    let entity =  NSEntityDescription.entityForName("Operatives", inManagedObjectContext: managedContext)

    var item: NSManagedObject!
    if let operativesList = self.operativesResult?.operativesList {
        self.operativesTable.removeAll()
        for itemInArray in operativesList {
            item = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
            item.setValue(itemInArray.firstName, forKey: "firstName")
            var error: NSError?
            if !managedContext.save(&error) {
            } else {
                self.operativesTable.append(item!)
                println("saveOperativesInModel: \(itemInArray.firstName)")
            }
        }
    }

    let fetchRequest1: NSFetchRequest! = NSFetchRequest(entityName:"Operatives")
    let fetchedResults = managedContext.executeFetchRequest(fetchRequest1, error: &error) as? [NSManagedObject]
    if let operativesTable = fetchedResults {
        if operativesTable.count > 0 {
            for item in operativesTable {
                let operative: Operative! = Operative()
                operative.firstName = String (stringInterpolationSegment: item.valueForKey("firstName"))
                println("getOperativesFromModel: \(operative.firstName)")
            }
        }
    }
}

回答1:


The Optional appears in the console because item.valueForKey returns an AnyObject?, an optional type. Since you're using the valueForKey value in your string interpolation segment, that value becomes optional. Therefore, the value being printed to the console is optional, and Swift automatically adds the Optional() wrapper around optional values in the console.

To avoid this behavior, you can either:

  • Force-unwrap the value from valueForKey by using the ! (force unwrap) operator, which would look something like this: String(stringInterpolationSegment: item.valueForKey("firstName")!), or
  • Use if let to check for a value and then print out the unwrapped value. For example:

    if let firstName = item.valueForKey("firstName") {
        operative.firstName = String(firstName)
        println("getOperativesFromModel: \(operative.firstName)")
    }
    



回答2:


It has already been answered why you see "Optional(...)" in the output. Here are some additional thoughts on how so solve the problem.

The reason that you wrote

operative.firstName = String (stringInterpolationSegment: item.valueForKey("firstName"))

is probably that a direct assignment

operative.firstName = item.valueForKey("firstName")

does not compile: The rhs has the type AnyObject?, whereas the lhs is a String.

A better solution would be an optional cast

if let firstName = item.valueForKey("firstName") as? String {
    operative.firstName = firstName
} else {
    // There is no first name, or it is not a String.
}

Or use the nil-coalescing operator ?? to provide a default value:

operative.firstName = item.valueForKey("firstName") as? String ?? "default name"

But what I would actually do is to let Xcode create NSManaged object subclass files for the Core Data entity (perhaps you even did that already?). Then you don't need the Key-Value coding methods anymore and can access the entities properties directly:

let fetchRequest1: NSFetchRequest! = NSFetchRequest(entityName:"Operatives")
let fetchedResults = managedContext.executeFetchRequest(fetchRequest1, error: &error) as? [Operatives]
if let operativesTable = fetchedResults {
    for item in operativesTable {
        let operative = Operative()
        operative.firstName = item.firstName
        println("getOperativesFromModel: \(operative.firstName)")
    }
}


来源:https://stackoverflow.com/questions/32455928/optional-wrapping-in-swift-why-does-swift-add-the-optional-to-the-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!