【问题标题】:Optional wrapping in Swift, why does Swift add the "Optional" to the stringSwift中的可选包装,为什么Swift要在字符串中添加“可选”
【发布时间】:2015-12-04 00:40:41
【问题描述】:

我将数组保存到模型中,保存数据时未使用 Optional (...) 包裹,但是在读取数据时,我得到 Optional(...) 包裹它。感谢您的帮助和耐心,因为我是 Swift 新手。

这是向模型添加值时的println

saveOperativesInModel: Test Name

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

getOperativesFromModel: Optional(Test Name)

为什么 Swift 会在字符串中添加“Optional(xxx)”?

这是精简后的代码:

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

【问题讨论】:

    标签: ios swift optional word-wrap


    【解决方案1】:

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

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

    • 使用!(强制解包)运算符强制解包valueForKey 中的值,如下所示:String(stringInterpolationSegment: item.valueForKey("firstName")!),或
    • 使用if let 检查一个值,然后打印出解包后的值。例如:

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

    【讨论】:

    • 谢谢(以及删除之前的评论 :) 那么解决方案是什么?我是否应该以一种避免 Optional() 的方式包装它,因为当我将此数组放入 TableView 时,我也得到了 Optional()
    【解决方案2】:

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

    你写的原因

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

    可能是直接分配

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

    无法编译:rhs 的类型为 AnyObject?,而 lhs 是String

    更好的解决方案是可选演员

    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 创建 NSManaged 对象 核心数据实体的子类文件(也许你甚至这样做了 已经?)。然后你就不再需要键值编码方法了 并且可以直接访问实体属性:

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

    【讨论】:

      猜你喜欢
      • 2017-03-26
      • 2016-07-11
      • 2015-12-03
      • 2020-12-10
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      相关资源
      最近更新 更多