那么你们能帮我解释一下,两者之间有什么不同吗?和 !在 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
如果authorObjor bookis 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!.booknilBook
现在,尝试分配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 。authorObjfourbookfive
局部变量book持有对 的强引用Book(),并且Book持有对 的强引用,所以当我们在 step中Author赋值时nil,无法释放 ,因为仍然持有对它的强引用。结束时,局部变量被释放,因此对它的强引用被释放,最后可以被释放,因为对它的最后一个强引用已经消失。authorObjfourauthorObjbooktestbookauthorObjauthorObj