我是 Swift 的初学者。我有一些问题需要解决,但我不能自己做。
这对我来说有些问题:
class Author {
weak var book: Book?
deinit {
print("Dealloc Author")
}
}
class Book {
var author: Author?
deinit {
print("Dealloc Book")
}
}
var authorObj:Author? = Author()
authorObj!.book = Book()
authorObj!.book!.author = authorObj
编译好:
class Author {
weak var book: Book?
deinit {
print("Dealloc Author")
}
}
class Book {
var author: Author?
deinit {
print("Dealloc Book")
}
}
var authorObj:Author? = Author()
authorObj!.book = Book()
authorObj!.book?.author = authorObj
authorObj = nil
authorObj!.book?.author = authorObj
和。{
authorObj!.book!.author = authorObj
? 我还有两个问题:
authorObj
是与authorObj.book.author
相同的强引用,它也是强引用?因为它在var。
weak
或unowned
只有authorObj.book
是弱引用。但是当我将authorObj
分配给nil时,所有都被删除了。为什么?我仅将authorObj
分配给nil,但Author()
实例仍然有1个强引用authorObj.book.author
答案 0 :(得分:1)
那么你们能为我解释一下,有什么不同之处?而且!在 authorObj!.book?。author = authorObj and authorObj!.book!.author = authorObj?
当您使用?
打开可选项时,它被称为可选链接。如果可选项为nil
,则整个链的结果将为nil
。使用?
的好处是,如果要解包的值为nil
,您的应用不会崩溃。
所以:
authorObj!.book?.author = authorObj
如果authorObj
为nil
,则会崩溃(因为强制展开 !
)。
和
authorObj!.book!.author = authorObj
如果authorObj
或book
为nil
,则会崩溃。
安全写这个的方式是:
authorObj?.book?.author = authorObj
如果authorObj
或book
为nil
,则不会执行任何操作和它不会崩溃。
authorObj是与authorObj.book.author相同的强引用,它是 强烈参考呢?因为在var之前它没有弱或没有。
在讨论弱与强时讨论单个变量才有意义。询问authorObj.book
是否弱是没有意义的;您可以说Author
拥有对book
的弱引用。
只有authorObj.book是弱引用。但是当我指定authorObj时 没有,都被删除了。为什么?我只将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
在步骤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
的强引用,因此不会立即释放它。
请注意,即使我们在步骤nil
中将authorObj
分配给four
,但在步骤book
之后取消分配five
之后才会取消分配。
本地变量book
包含对Book()
的强引用,而Book
包含对{{1}的强引用因此,当我们在步骤Author
中将nil
分配给authorObj
时,four
无法释放,因为authorObj
仍然拥有强引用它。当book
结束时,将释放局部变量test
,因此释放了对book
的强引用,最后可以释放authorObj
authorObj
最后强的引用已经消失。