Swift中可选的包装,为什么Swift将“可选”添加到string

我将一个数组保存到模型中,当保存数据不包含可选(…),但是当数据正在读取时,我得到可选(…)环绕它。 感谢您的帮助和耐心,因为我是Swift新手。

在将值添加到模型时,这是println

 saveOperativesInModel: Test Name 

从模型中读取值时,这是println

 getOperativesFromModel: Optional(Test Name) 

为什么Swift将“Optional(xxx)”添加到string?

这是简化的代码:

 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)") } } } } 

Optional出现在控制台中,因为item.valueForKey返回一个AnyObject? ,一个可选的types。 由于您在string插值段中使用了valueForKey值,因此该值变为可选。 因此,打印到控制台的值是可选的,Swift自动在控制台中添加Optional()包装可选值。

为了避免这种行为,您可以:

  • 通过使用!强制展开valueForKey的值 (force unwrap)运算符,它看起来像这样: String(stringInterpolationSegment: item.valueForKey("firstName")!) ,或者
  • 使用, if let检查一个值,然后打印出解包值。 例如:

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

已经回答了为什么在输出中看到“可选(…)”。 以下是关于如何解决问题的一些额外的想法。

你写的原因

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

大概是一个直接的任务

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

不编译:rhs有AnyObject?typesAnyObject? 而lhs是一个String

更好的解决scheme将是一个可选的演员

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

或者使用nil-coalescing操作符?? 提供默认值:

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

但是我真正要做的是让Xcode为Core Data实体创buildNSManaged对象子类文件(也许你甚至已经这样做了?)。 那么您不再需要Key-Value编码方法,并且可以直接访问实体属性:

 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)") } }