我是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
那么你们能为我解释一下,两者之间有什么区别吗? 和 ! 作者Obj!.书?。author = authorObj 和 authorObj!.书!。作者 = 作者Obj?
当您使用?
解开可选包时,它被称为可选链接。 如果可选是nil
,则整个链的结果将nil
。 使用?
的优点是,如果解包的值为nil
,则应用不会崩溃。
所以:
authorObj!.book?.author = authorObj
如果nil
authorObj
,将崩溃(因为强制解包!
)。
和:
authorObj!.book!.author = authorObj
如果authorObj
或book
nil
,将崩溃。
编写此内容的安全方法是:
authorObj?.book?.author = authorObj
如果authorObj
或book
nil
,这将不执行任何操作,也不会崩溃。
authorObj是一个与authorObj.book.author相同的强参考,它是 强参考也?因为它在var之前没有弱或无主。
在谈论弱与强时,只谈论单个变量才有意义。 问authorObj.book
是否虚弱是没有意义的;你可以说Author
对book
的引用很弱。
只有作者Obj.book是弱参考。但是当我将作者 Obj 分配给 没有,都是被淘汰的。为什么?我只将作者 Obj 分配给零,但 Author() 实例仍然有 1 个强引用作者 Obj.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
崩溃,因为自从刚刚分配给它的Book
被释放以来authorObj!.book
nil
。
现在,尝试将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
的强引用,因此它不会立即释放。
请注意,即使我们在步骤four
中将nil
分配给authorObj
,直到步骤five
之后才释放book
。
局部变量book
持有对Book()
的强引用,而Book
持有对Author
的强引用,所以当我们在步骤four
中将nil
分配给authorObj
时,authorObj
不能被释放,因为book
仍然持有对它的强引用。 当test
结束时,局部变量book
被释放,因此对authorObj
的强引用被释放,最后authorObj
可以释放,因为对它的最后一个强引用已经消失。