在 《 Swift编程语言》 (Apple书)中,我读到可以用两种方式创建可选变量:使用问号(?)或使用感叹号(!)。
区别在于,当使用(?)获得可选值时,每次需要该值时都必须使用感叹号:
var str: String? = "Question mark?" println(str!) // Exclamation mark needed str = nil
使用(!)时,您可以不带后缀:
var str: String! = "Exclamation mark!" println(str) // No suffix needed str = nil
有什么区别?如果根本没有区别,为什么有2种方法呢?
当两个类相互指向并且您需要避免强引用循环时,使用隐式解开的可选变量(用!声明)的真正好处与类初始化有关。例如:
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 } }
现在,
self
instanceOfB
但是,一旦创建了A,就不得不使用instanceOfB访问instanceOfB!因为我们 知道 必须有一个B
为了避免这种情况,instanceOfB被声明为一个隐式未包装的可选(instanceOfB!),我们可以仅使用instanceOfB对其进行访问。(此外,我 怀疑 编译器也可以不同地优化访问)。
这本书的第464至466页给出了一个示例。