Swift下Cocoa框架中的NSMetadataItem
类包含以下函数:
func valueForAttribute(key: String!) -> AnyObject!
我还在学习强制解包和可选链接之间的区别(和细节)。在上面的函数中,这是否意味着:
key
参数必须包含值,
保证返回值具有值?
我主要关注的是返回值后面的感叹号 - 一旦我分配了返回值:
var isDownloadedVal = item.valueForAttribute(NSMetadataUbiquitousItemIsDownloadedKey)
我在检查时是否需要包含if let
块,或者我保证它会有一个我可以安全检查的值吗?
答案 0 :(得分:19)
TLDR:将Foo!
视为Foo
。
许多Cocoa调用包括隐式解包的选项,并且它们对它的需求很可能是该特征存在的原因。以下是我的建议。
首先,让我们考虑一个不涉及AnyObject
的简单案例。我认为UIDevice
是一个很好的例子。
class func currentDevice() -> UIDevice!
这里发生了什么?好吧,总有currentDevice
。如果返回nil
,则表明系统中存在某种深度错误。因此,如果我们在Swift中构建此接口,则可能只返回UIDevice
并完成它。但我们需要桥接到Objective-C,它返回UIDevice*
。现在不应该是nil
,但语法上可以是nil
。现在在ObjC中,我们通常会忽略这一事实并且不要nil
- 请在此处查看(特别是因为nil
- 消息传递通常是安全的。)
那么我们如何在Swift中表达这种情况呢?嗯,从技术上来说它是一个Optional<UIDevice>
,你最终得到了:
class func currentDevice() -> UIDevice?
并且您每次使用它时都需要明确地解开它(理想情况下使用if let
块)。这很快会让你疯狂,无所事事。 currentDevice()
始终返回一个值。 Optional
是与ObjC桥接的工件。
所以他们发明了一个黑客来解决这个问题(我认为这真的是一个黑客;如果ObjC不在混合中,我无法设想构建这个功能)。那个黑客说,是的,它是一个Optional
,但你可以假装它不是,我们保证它永远是一个价值。
那是!
。对于这种类型的东西,你基本上忽略!
并假装它将你送回UIDevice
并滚动。如果他们骗你并返回nil
,那么,那将会崩溃。他们不应该骗你。
这表明一条规则:除非你真的需要,否则不要使用!
(而且你几乎只需要在与ObjC建立联系时)。
在您的具体示例中,这适用于两个方向:
func valueForAttribute(key: String!) -> AnyObject!
从技术上讲,它需要Optional<String>
,但仅限于它与NSString*
的桥接。您必须在此处传递非nil
。从技术上讲,它会返回Optional<AnyObject>
,但仅限于它与id
的桥接。它承诺它不会成为nil
。
答案 1 :(得分:1)
根据Swift-eBook,其中陈述以下内容
“正在尝试使用!访问不存在的可选值会触发运行时错误。在使用之前,请务必确保可选项包含非零值!强行解开它的价值。“
我会用是回答你的前两个问题。
检查时是否需要包含if let块?
否,这不是必需的。