【问题标题】:swift optional chaining with cast快速可选链接与演员
【发布时间】:2014-07-11 18:01:06
【问题描述】:

下面的代码突出显示了我在将可选链接和强制转换与 Apple 的 swift 语言相结合时遇到的问题

import Foundation
import CoreData

class MyExample {

    var detailItem: NSManagedObject?

    func example() {
        //In the actual implementation it is assigned to a UITableViewCell textLabel.text with the same result.
        let name: String = self.detailItem?.valueForKey("name") as String
    }
}

以上结果:

'AnyObject' 不能转换为 'String'

我可以通过将类变量设为隐式展开的可选变量来做到这一点,如下所示:

class MyExample2 {

    var detailItem: NSManagedObject!

    func example() {
        let name: String = self.detailItem.valueForKey("name") as String
    }
}

这可行,但现在这个变量并不能反映我的现实世界需要它是可选的

下一个示例也适用于可选的 detailItem:

class MyExample3 {

    var detailItem: NSManagedObject?

    func example() {
        let name: String = self.detailItem?.valueForKey("name").description as String
    }
}

上面的问题是我不得不使用描述。使用此函数的输出向用户显示通常不是一个好主意(根据 Apple,只是常识)

上述方法也仅适用于我 am 正在寻找一个字符串。如果我需要一个对象,它就行不通。

作为一个有趣的点,这个例子抛出了一个不同的错误:

class MyExample4 {

    var detailItem: NSManagedObject?

    func example() {
        let name: String = self.detailItem?.valueForKey("name")
    }
}

以上抛出:

找不到成员“valueForKey”

NSmanagedObject 显然有一个 valueForKey。

再尝试一件事,我发现了一个潜在的解决方案:

class MyExamplePotentialSolution {

    var detailItem: NSManagedObject?

    func example() {
        let name: NSString = self.detailItem?.valueForKey("name") as NSString
    }
}

上面的问题是,当实际分配给 UITableViewCell detailTextLabel.text 属性时它不起作用。

有什么想法吗?

更新答案

现实世界中最简单的用法原来是这样的:

cell.detailTextLabel.text = self.detailItem?.valueForKey("name") as? NSString

关键是 AnyObject 不能直接转换为原生 swift 类型。正如公认的答案所示,它可以从 NSString 转换为原生 Swift 字符串。在这种情况下就没有必要了。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    有2个问题:第一个是在这一行:

    let name: String = self.detailItem?.valueForKey("name") as String
    

    右侧部分是可选的(detailItem 是可选的),因此无论表达式返回什么,都不能将其分配给类型为 String 的非可选变量

    第二个问题是valueForKey 返回AnyObject!,它可以是任何类的实例 - 但String 不是类,您需要Any 才能将其转换为String。 我假设NSManagedObject 返回一个NSString,所以你可以用这行来实现你所需要的:

    let name: String? = (self.detailItem?.valueForKey("name") as? NSString) as? String
    

    【讨论】:

    • 这是我在潜在的固定版本中尝试过的事情之一。这是我尝试过的: cell.detailTextLabel.text = self.detailItem?.valueForKey("name") as NSString; // 这不仅不会编译,而且会导致 xcode 中的 sourcekit 崩溃
    • 这确实有效:让名称:字符串? = (self.detailItem?.valueForKey("name") as?NSString) as?字符串 cell.detailTextLabel.text = 名称
    猜你喜欢
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    相关资源
    最近更新 更多