swift可选链接与演员 [英] swift optional chaining with cast

查看:167
本文介绍了swift可选链接与演员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The code below highlights a problem I'm having combining optional chaining and casts with Apple's swift language

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'

'AnyObject' is not convertible to 'String'

我可以通过使类变量成为隐式解包的可选项来实现,如下所示:

I am able to do this by making the class variable an implicitly unwrapped optional as follows:

class MyExample2 {

    var detailItem: NSManagedObject!

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

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

This works, but now this variable doesn't reflect my real world need for it to be optional

下一个示例也适用于detailItem作为可选项:

This next example also works with detailItem as optional:

class MyExample3 {

    var detailItem: NSManagedObject?

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

以上问题是我必须使用说明。使用此功能的输出向用户显示通常不是一个好主意(根据Apple,只是常识)

The problem with the above is I had to use description. It's generally not a good idea to use output from this function to show to the user (according to Apple, and just common sense)

以上也只能起作用,因为我 am 正在寻找一个字符串。如果我需要一个对象,它将无法工作。

The above also only works because I am looking for a string. If I needed an object, it wouldn't work.

作为一个兴趣点,这个例子引发了一个不同的错误:

As a point of interest this example throws a different error:

class MyExample4 {

    var detailItem: NSManagedObject?

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

上述抛出:


不能find member'valueForKey'

Could not find member 'valueForKey'

NSmanagedObject显然有一个valueForKey。

NSmanagedObject clearly has a valueForKey.

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

Trying one more thing, I discovered a potential solution:

class MyExamplePotentialSolution {

    var detailItem: NSManagedObject?

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

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

The problem with the above, is it doesn't work when actually assigned to a UITableViewCell detailTextLabel.text attribute.

任何想法?

更新答案

最简单的现实世界用法是:

The simplest real world usage turned out to be this:

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

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

The key is AnyObject can't be cast to a native swift type directly. As the accepted answer showed, it can be cast as a native Swift string from NSString. It just isn't necessary in this case.

推荐答案

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

There are 2 problems: the first is that in this line:

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

右边的部分是可选的( detailItem 是可选的),所以无论表达式返回什么,它不能分配给类型字符串

the right part is an optional (detailItem is optional), so whatever the expression returns, it cannot be assigned to a non-optional variable having type String

的非可选变量第二个问题是 valueForKey 返回 AnyObject!,它可以是任何类的实例 - 但是 String 不是一个类,你需要任何才能将它转换为 String
我假设 NSManagedObject 返回 NSString ,因此您可以通过以下行获得所需:

The second problem is that valueForKey returns AnyObject!, which can be an instance of any class - but String is not a class, you'd need Any in order to be able to cast that into a String. I presume that NSManagedObject returns an NSString, so you can achieve what you need with this line:

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

这篇关于swift可选链接与演员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆