2017-10-21 98 views
1

我在awakeFromNib函数中创建了一个局部变量,在一个UIView动画块中使用它,但它永远不会被释放,为什么?Swift,为什么这个本地变量不被释放?

这里是(在一个UITableViewCell内awakeFromNib)代码

var fullPhotoDisposeBag = DisposeBag() 
fullScreenImageView.rx.tapGesture().when(UIGestureRecognizerState.recognized).subscribe(onNext: { (tap) in 

     UIView.animate(withDuration: 0.15, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: { 
      fullScreenImageView.frame = oldFullScreenFrame 
     }, completion: { (finished) in 
      fullScreenImageView.removeFromSuperview() 
      let _ = fullPhotoDisposeBag //This line avoid early release, but retains too much... 
     }) 
}, onDisposed:{ 
     print("disposed") 
}).addDisposableTo(fullPhotoDisposeBag) 

一个线索是,的tableView是在我的应用程序的一个选项卡的根,所以UITableView的是永远不会释放因此的UITableViewCell是从来由于可重用性而被释放。 但为什么ARC会保留这个变量?仅用于功能和完成块?

PS:我目前使用的可选DisposeBag我在完成块设置为零,但我不明白为什么我需要做的......

回答

1

看起来像一个保留周期。我的猜测是,垃圾收集器不会释放局部变量,直到完成闭包停止引用它,并且完成闭包永远不会被释放,因为它由本地函数拥有。

我的建议是将这段代码从你的UIView移走到你的UIViewController,因为那是应该定义这种行为的地方。

+0

谢谢,这正是我的想法。我将代码移动到viewController,不幸的是,我认为没有其他方式与rxSwift这样的情况比声明disposeBag可选,强制解包时添加到disposeBag(我讨厌使用“!”),然后设置disposeBag在动画完成时为零 – Devous

+0

在完成块中执行'fullPhotoDisposeBag = DisposeBag()'怎么办?这应该足以清空原来的'DisposeBag',打破保留周期,而不需要引入'Optional'。 –