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