代码之家  ›  专栏  ›  技术社区  ›  Emre Önder

解除ViewController不会释放Swift中的内存

  •  2
  • Emre Önder  · 技术社区  · 7 年前

    我有一个viewcontroller(我们称之为TableViewController)。当用户轻触自定义UITableViewCell内的按钮时,将打开一个新的视图控制器(称为DetailViewcontroller)。当用户点击DetailViewController内的后退按钮时,我调用了Disclose函数,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 回复  |  直到 7 年前
        1
  •  2
  •   Reinier Melian    7 年前

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

    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
        }
    
    }
    
        2
  •  0
  •   Ayoub Khayati    7 年前

    首先确保 detailViewController 是导致泄漏的物体。

    deinit {
     print("detailViewController deallocated")
    }
    

    如果不调用Denit,则有很强的引用保留 详细信息查看控制器 活着的检查内部是否有封口 detailViewController 在这里,你使用self而没有弱引用。或是你保存参考资料的地方 detailViewController 在里面 TableViewController