我是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
最佳答案
你们能为我解释一下,两者之间有何不同?和!在
authorObj!.book?.author = authorObj和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
拥有对Author
的强引用,因此,当我们在步骤nil
中将authorObj
分配给four
时,authorObj
可以无法释放,因为book
仍然对其有很强的引用。当test
结束时,将释放局部变量book
,因此将释放对authorObj
的强引用,最后,由于对它的最后一个强引用消失了,最终可以将authorObj
释放。