3 回答
TA贡献1887条经验 获得超5个赞
当两个类相互指向并且您需要避免强引用循环时,使用隐式展开的可选变量(用!声明)的真正好处与类初始化有关。例如:
A级<-> B级
A类的初始化例程需要创建(并拥有)B类,而B需要对A的弱引用:
class A {
let instanceOfB: B!
init() {
self.instanceOfB = B(instanceOfA: self)
}
}
class B {
unowned let instanceOfA: A
init(instanceOfA: A) {
self.instanceOfA = instanceOfA
}
}
现在,
B类需要引用要初始化的A类。
A类只有self在完全初始化后才能传递给B类的初始化器。
为了使A类在创建B类之前被视为已初始化,instanceOfB因此该属性必须是可选的。
但是,一旦创建了A,就不得不使用instanceOfB访问instanceOfB会很烦人!因为我们知道必须有一个B
为了避免这种情况,instanceOfB被声明为一个隐式未包装的可选(instanceOfB!),我们可以仅使用instanceOfB对其进行访问。(此外,我怀疑编译器也可以不同地优化访问)。
这本书的第464至466页给出了一个示例。
摘要:
采用 ?如果该值将来可能变为nil,以便对此进行测试。
采用 !如果将来它真的不应该变为零,但是最初需要为零。
TA贡献1796条经验 获得超4个赞
您应该超越语法糖。
有两种完全不同的多态类型。语法糖仅使用这些类型中的一种或另一种。
当你Foo?以类型写作时,你确实拥有Optional<Foo>,而当你写作时,Foo!你确实具有ImplicitlyUnwrappedOptional<Foo>。
这是两种不同的类型,它们也有所不同Foo。
TA贡献1772条经验 获得超8个赞
?(可选)表示您的变量在
!时可能包含nil值。(解包器)表示在运行时使用变量(尝试从中获取值)时,变量必须具有内存(或值)。
主要区别在于,当可选值为nil时,可选链接会正常失败,而当可选值为nil时,强制展开会触发运行时错误。
为了反映可以在nil值上调用可选链接的事实,即使要查询的属性,方法或下标返回非可选值,可选链接调用的结果也始终是可选值。您可以使用此可选返回值来检查可选链接调用是否成功(返回的可选包含一个值),或者由于链中的值为nil而失败(返回的可选值为nil)。
具体来说,可选链接调用的结果与预期返回值的类型相同,但包装在可选中。通常返回Int的属性将返回Int?通过可选链访问时。
var defaultNil : String? // declared variable with default nil value
println(defaultNil) >> nil
var canBeNil : String? = "test"
println(canBeNil) >> optional(test)
canBeNil = nil
println(canBeNil) >> nil
println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper
var canNotBeNil : String! = "test"
print(canNotBeNil) >> "test"
var cantBeNil : String = "test"
cantBeNil = nil // can't do this as it's not optional and show a compile time error
- 3 回答
- 0 关注
- 461 浏览
添加回答
举报