那么你们能帮我解释一下,两者之间有什么不同吗?和 !在 authorObj!.book?.author = authorObj 和 authorObj!.book!.author = authorObj?
当您使用?
解包可选时,它被称为可选链接。如果可选的是nil
,则整个链的结果将是nil
。使用的好处?
是,如果被解包的值为nil
.
所以:
authorObj!.book?.author = authorObj
authorObj
如果是nil
(因为强制 unwrap )会崩溃!
。
和:
authorObj!.book!.author = authorObj
authorObj
如果要么book
是将崩溃nil
。
写这个的安全方法是:
authorObj?.book?.author = authorObj
如果authorObj
or book
is nil
,这将什么也不做,也不会崩溃。
authorObj 和 authorObj.book.author 一样是强引用,它也是强引用吗?因为它在 var 之前没有弱或无主。
在谈论weak与strong时,谈论一个变量才有意义。authorObj.book
问是否弱是没有意义的;你可以说它对 .Author
的引用很弱book
。
只有 authorObj.book 是弱参考。但是当我将 authorObj 分配给 nil 时,所有的都被取消了。为什么?我只将 authorObj 分配给 nil 但 Author() 实例仍然有 1 个强引用 authorObj.book.author
当您分配nil
给 时authorObj
,这是对 的最后一个强引用authorObj
,因此自动引用计数 (ARC)会递减引用计数器,然后释放 中的所有引用authorObj
。如果这些是强引用,它会减少引用计数,如果那是对该对象的最后一个引用,则该对象也被释放。如果任何其他对象持有对任何已释放对象的弱引用,则ARC将nil
在所有弱指针中设置该值。
要在操场上进行测试,请将您的命令放在一个名为test
并添加print
语句的函数中,以便您可以看到事情何时发生。
class Author {
weak var book: Book?
deinit {
print("Dealloc Author")
}
}
class Book {
var author: Author?
deinit {
print("Dealloc Book")
}
}
func test() {
print("one")
var authorObj: Author? = Author()
print("two")
authorObj!.book = Book()
print("three")
authorObj!.book?.author = authorObj
print("four")
}
test()
输出:
one
two
Dealloc Book
three
four
Dealloc Author
需要注意的是,Book
在 step 之前已解除分配three
。为什么?因为没有强有力的指示。您分配了它,然后将对它的唯一引用分配给Author内部的弱指针,因此ARC立即释放了它。
这就解释了为什么会authorObj!.book!.author = authorObj
崩溃,因为刚刚分配给它的那个已经被释放了。authorObj!.book
nil
Book
现在,尝试分配Book()
给局部变量book
:
func test() {
print("one")
var authorObj: Author? = Author()
print("two")
let book = Book()
authorObj!.book = book
print("three")
authorObj!.book?.author = authorObj
print("four")
authorObj = nil
print("five")
}
test()
这一次,输出完全不同:
one
two
three
four
five
Dealloc Book
Dealloc Author
现在,局部变量book
持有对已分配的 的强引用Book
,因此它不会立即被释放。
请注意,即使我们在 step中分配nil
了 to ,它也不会被释放,直到 after被释放后 step 。authorObj
four
book
five
局部变量book
持有对 的强引用Book()
,并且Book
持有对 的强引用,所以当我们在 step中Author
赋值时nil
,无法释放 ,因为仍然持有对它的强引用。结束时,局部变量被释放,因此对它的强引用被释放,最后可以被释放,因为对它的最后一个强引用已经消失。authorObj
four
authorObj
book
test
book
authorObj
authorObj