我试图使用guard语句来检查nil。
我很困惑为什么以下内容让它漏掉并产生BAD_EXEC错误:
guard let event:Event! = eventsImagesLoading.removeValueForKey(location) else {
return
}
images[location] = responseData
event!.iconImgData = images[location]
我试图检查"事件"方法调用后为零。如果它是它应该返回。但实际上它会在事件中滑倒并崩溃!.iconImageData ... line。
答案 0 :(得分:5)
其他答案向您展示如何解决您的问题,但并未真正解释为什么会出现此错误,所以我认为我会参与其中。
guard let ... else
语句与if let ...
非常相似,尝试将可选的unwrapped值绑定到一个非nil
---可选的不可变的相同底层类型;使用可选绑定
var a: Int? = 5
if let b = a {
// b unwrapped, type inferred to non-optional type Int
print(b) // "5"
}
如果a
的值为nil
,则b
为Int
,默认情况下(按类型推断),类型为nil
的类型b
无法保留,则上述绑定将失败a
。
在这种情况下,将b
显式声明为隐式展开的可选项是没有意义的,因为即使a
为nil,这也将允许成功绑定。等效的非感知块将明确声明Int?
是可选的,然后将可选b
(Int?
)的“尝试可选绑定”转换为可选if let ...
( a = nil
if let b: Int! = a {
print(b) // "nil"
// wups, we managed to bind a to b even though a is nil ...
// note also this peculiarity
print(b.dynamicType) // Optional<Int>
let c: Int! = nil
print(c.dynamicType) // ImplicitlyUnwrappedOptional<Int>
}
if let b: Int? = a {
print(b) // nil
// wups, we managed to bind a to b even though a is nil ...
}
}自然会一直成功,b
块会减少为完全冗余的块本地分配。
Int?
注意特殊性,无论我们是否明确指定Int!
为b
类型(可选)或类型if let
(隐式展开可选),绑定不可变{{1}在两种情况下,传入Int?
块只是一个常规可选(类型为event
)。这解释了为什么您需要在<{em} event!.iconImgData
子句之后展开guard let
(guard let ... else
),即使我们声明它是隐式展开的类型。
因此,在您的示例中,eventsImagesLoading.removeValueForKey(location)
语句不会捕获nil
为event
的情况,作为对Event!
的绑定(隐式解包的可选类型) nil
)即使对func foo() {
let bar : Int? = nil
guard let _: Int! = bar else {
print("this is surely nil")
return
}
print("but an implicitly unwrapped optional will fall through")
}
foo() // "but an implicitly unwrapped optional will fall through"
个案件也会成功。
nil
对于需要延迟初始化(值nil
直到初始化)的不可变项,通常只应使用隐式解包的选项。在初始化隐式展开的可选项之后,其值永远不应该是nil
(而在上面的示例中,它的值是,在通过可选绑定初始化之后,只是那个; guard let INFER_THIS = ... else
)。
此外,您通常应该让编译器推断您尝试在if let INFER_THIS = ...
或./configure
make ASTLDFLAGS="-lcurl"
make install
make samples
make config
子句中绑定的不可变的非可选类型。 / p>
我们可以思考是否应该允许使用可选绑定到可选类型(保证成功),但这是另一个讨论。
答案 1 :(得分:3)
将Event!
更改为Event
(第1行),将event!
更改为event
(第5行)。
答案 2 :(得分:1)
guard let event:Event = eventsImagesLoading.removeValueForKey(location) else {
return
}
images[location] = responseData
event.iconImgData = images[location]