在下面的代码中,self.tableView.reloadData()中的self是否作为强引用存在问题,应该将其更改为弱引用,还是可以这样?
class SomeViewController : UIViewController {
fileprivate var notificationToken: NotificationToken? = nil
...
override func viewDidLoad()
{
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(onNotification), name: NSNotification.Name(SomeNotification), object: nil)
realmNotificationToken = blockedList.observe({ (changes: RealmCollectionChange) in
switch changes
{
case .initial:
self.tableView.reloadData() // Case 1
break
...
@objc func onNotification()
{
DispatchQueue.main.async{
self.tableView.reloadData() // Case 2
}
}
在这两个示例中,由于self是强引用,因此保留周期是否存在任何问题,应该将其更改为弱引用? 在这两种情况下,使用self.tableView.reloadData()的两个块的寿命是多少?如果一生都是短暂的,那么使用强壮没有问题,这些块寿命长吗?
答案 0 :(得分:1)
案例2是一个不可逃脱的闭包,因此没有问题。
案例1是@escaping
,因此您需要使用weak
或unowned
引用。 @escaping
表示您正在将闭包传递给可能比创建闭包的对象(即您的ViewController)更持久的对象。如果您在self
中强烈捕获@escaping
,则ViewController现在的生存时间与闭包寿命一样长,并且闭包寿命一直到取消订阅为止。如果您仅在ViewController取消初始化时取消订阅,则现在有一个循环。因为订阅永远不会死,而闭包永远不会被释放,而ViewController也不会因为订阅永不死,所以它不会被释放。
编辑: 我要补充一点,无论哪种情况,您实际上都不需要自我。您可以简单地捕获tableview(如果将其隐式展开,则将其分解为一个普通的可选对象,这很好):
realmNotificationToken = blockedList.observe({ [tableView] (changes: RealmCollectionChange) in
switch changes {
case .initial:
tableView?.reloadData()