解散ViewController并不会在Swift中释放内存

时间:2018-04-16 08:49:58

标签: ios swift memory uiviewcontroller

我有一个viewcontroller(让我们称之为TableViewController)。当用户点击自定义UITableViewCell中的按钮时,会打开一个新的视图控制器(称为DetailViewcontroller)。当用户点击DetailViewController中的后退按钮时,我调用了dismiss函数,并再次打开TableViewController。

我的问题是,当我这样做50次时,内存使用量会增加。所以我猜它没有做任何解除分配。

Memory Usage

我如何打开DetailViewController;

    @objc func voteBtnTapped(_ sender: UIButton){
    guard let team = FirebaseManager.instance.currentTeam else { return }
    FirebaseManager.instance.delegate = nil
    let voteController = VoteViewController()
    voteController.currentTeam = team
    let transition = CATransition()
    transition.duration = 0.5
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromRight
    transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
    view.window!.layer.add(transition, forKey: kCATransition)
    self.present(voteController, animated: false, completion: nil)
}

我如何解雇DetailViewController;

    @objc func backBtnTapped(_ sender: UIButton){
    FirebaseManager.instance.delegate = nil
    let transition = CATransition()
    transition.duration = 0.5
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromLeft
    transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
    view.window!.layer.add(transition, forKey: kCATransition)
    self.dismiss(animated: false, completion: nil)
}

它说器具泄漏,但我无法弄清楚,这些韭菜是什么原因。

enter image description here

编辑:我发现我使用的(在DetailViewController中)的选择器库阻止了重新分配。你知道为什么阻止它,我该如何处理呢?

从回复回答我如何声明pickerView:

 let config = AZAPickerConfiguration<PickerItem>(items: (1...10).map { PickerItem(number: $0) },
                                                    defaultSelectedIndex: 4,
                                                    selectedFont: UIFont(name: "SourceSansPro-SemiBold", size: 50)!, nonSelectedFont:UIFont(name: "SourceSansPro-Light", size: 20)!, selectionRadiusInPercent: 0.5,
                                                    selectionBackgroundColor: UIColor(red:0.00, green:0.42, blue:0.20, alpha:1.0), itemWidth: 80)

    self.pickerView = AZAPicker<PickerItem>(with: config, frame: .zero)

    pickerView!.backgroundColor = .white
    pickerView!.translatesAutoresizingMaskIntoConstraints = false
    //self.pickerView!.onPickItem = self.picker
    self.pickerView!.onPickItem = {( sender : AZAPicker<PickerItem>,item:PickerItem) in
        print("didPickItem: \(item)")
        self.currentPoint = item.number

    }

https://github.com/AvanzaBank/AZAPicker

2 个答案:

答案 0 :(得分:2)

该库似乎在使用表单中有错误,在示例代码中声明了这样的方法

func picker(sender: AZAPicker<PickerItem>, item: PickerItem) {
    print("didPickItem: \(item)")
}

但不要这样做,你需要以这种方式分配一个闭包,问题解决了

更新(在您的代码中)

self.pickerView!.onPickItem = {[weak self]( sender : AZAPicker<PickerItem>,item:PickerItem) in
    print("didPickItem: \(item)")
    self.currentPoint = item.number

}

完整代码参考

class ViewController: UIViewController {

    @IBAction func dismiss(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        let config = AZAPickerConfiguration<PickerItem>(items: (1...100).map { PickerItem(number: $0) },
                                           defaultSelectedIndex: 99,
                                           selectionRadiusInPercent: 0.5,
                                           itemWidth: 80)

        let pickerView = AZAPicker<PickerItem>(with: config, frame: .zero)

        pickerView.backgroundColor = .white
        //in this code [weak self] is not needed because I don't use self inside the closure
        pickerView.onPickItem = {( sender : AZAPicker<PickerItem>,item:PickerItem) in
            print("didPickItem: \(item)")
        }

        pickerView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(pickerView)

        NSLayoutConstraint(item: pickerView, attribute: .top, relatedBy: .equal, toItem: topLayoutGuide, attribute: .top, multiplier: 1, constant: 20).isActive = true

        NSLayoutConstraint(item: pickerView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0).isActive = true

        NSLayoutConstraint(item: pickerView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0).isActive = true

        NSLayoutConstraint(item: pickerView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 80).isActive = true
    }

}

答案 1 :(得分:0)

首先确保 detailViewController 是导致泄漏的对象。

deinit {
 print("detailViewController deallocated")
}

如果没有调用deinit,那么有一个强大的引用使 detailsViewController 保持活动状态。检查你是否在 detailViewController 中有闭包,你在那里使用self而没有弱引用。或者在 TableViewController 中保留 detailViewController 引用的地方。