两者之间有什么不同?和!在弱中,在斯威夫特中的强引用



我是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 = authorObjauthorObj!.book!.author = authorObj

我还有两个问题:

  • authorObj强参考和authorObj.book.author一样,也是强参考?因为它在var之前没有weakunowned

  • 只有authorObj.book是弱引用。但是当我authorObj分配给 nil 时,所有这些都是被取消的。为什么?我只将authorObj分配给 nil,但Author()实例仍然有 1 个强引用authorObj.book.author

那么你们能为我解释一下,两者之间有什么区别吗? 和 ! 作者Obj!.书?。author = authorObj 和 authorObj!.书!。作者 = 作者Obj?

当您使用?解开可选包时,它被称为可选链接。 如果可选是nil,则整个链的结果将nil。 使用?的优点是,如果解包的值为nil,则应用不会崩溃。

所以:

authorObj!.book?.author = authorObj

如果nilauthorObj,将崩溃(因为强制解包!)。

和:

authorObj!.book!.author = authorObj

如果authorObjbooknil,将崩溃。

编写此内容的安全方法是:

authorObj?.book?.author = authorObj

如果authorObjbooknil,这将不执行任何操作也不会崩溃。

authorObj是一个与authorObj.book.author相同的强参考,它是 强参考也?因为它在var之前没有弱或无主。

在谈论时,只谈论单个变量才有意义。 问authorObj.book是否虚弱是没有意义的;你可以说Authorbook的引用很弱

只有作者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!.booknil


现在,尝试将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可以释放,因为对它的最后一个引用已经消失。

相关内容

  • 没有找到相关文章

最新更新