swift可选链接与演员 [英] swift optional chaining with cast
问题描述
下面的代码突出显示了我将可选链接和强制转换与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屋!