Как деинитировать класс CollectionView

В моем проекте есть 2 ViewController'а (ViewController и DetailViewController). На первом есть табличный вид в UIScrollview. На втором — кнопки в UICollectionView с изображениями и ссылками. Когда я много раз всплываю в DetailViewController, приложение начинает тормозить, и я вижу утечку памяти на графике. Также в памяти отладки я вижу 18 объектов CollectionViewCell и 3 DetailViewController. Первую утечку CellProps я решаю следующим образом:

   override func viewDidDisappear(_ animated: Bool) {
    btnArray.removeAll()

Как решить эту утечку памяти?

ViewController.swift

import UIKit
import BetterSegmentedControl
import Firebase

class ViewController: UIViewController, UIScrollViewDelegate, UITableViewDelegate {

    var ICOListGoingOn = [ICOs] ()
    var ICOListEnded = [ICOs] ()
    var ICOListnotstarted = [ICOs] ()
    @objc func reload(n: NSNotification) {
        SaveLikedArray()
        self.icoArraySort()
        let slide = SlideView(frame: CGRect(x: view.frame.width * CGFloat(0), y: 0, width: view.frame.width, height: slideScrollView.frame.height))
        slide.ICO = ICOListLiked
        slide.delegate = self
        slideScrollView.addSubview(slide)
    }


extension ViewController: SlideViewDelegate{
    func tableCellSelected(tableView: UITableView, indexPath: IndexPath, ico: ICOs) {
//        print("Table tag : \(tableView.tag) Selcted Row : \(indexPath.row) Selected Value : \(ico)")
        if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController{
            controller.ICO = ico
            ICOId = ico.ICOId
            self.navigationController?.pushViewController(controller, animated: true)
        }
    }
}

CollectionViewCell.swift

import UIKit

class CellProps {
    var image: UIImage!
    var url: String!
    init (image: UIImage, url: String) {
        self.image = image
        self.url = url
    }
    deinit {
        print("CellProps")
    }
}
protocol CollectionViewCellDelegate {
    func didButtonClick(url: String)
} 
class CollectionViewCell: UICollectionViewCell {
    var delegate: CollectionViewCellDelegate!
    weak var CellItem: CellProps!
    @IBOutlet weak var btnICONOutlet: UIButton!
    @IBAction func btnICONAction(_ sender: Any) {
        delegate?.didButtonClick(url: CellItem.url)
    }
    func setCell(cell: CellProps) {
        CellItem = cell
        CellItem.url = cell.url
        btnICONOutlet.setImage(cell.image, for: .normal)
    }
    deinit {
        print("CollectionViewCell")
    }
}

DetailViewController.swift

import UIKit
class DetailViewController: UIViewController  {
    var ICO: ICOs!
    var btnArray: [CellProps] = []
    var timer: Timer?

    @IBOutlet weak var outCollectioView: UICollectionView!
    @IBOutlet weak var btnLike: LikeButton!
    @IBAction func btnLikeAction(_ sender: Any) {
        if !btnLike.isOn {
            let ind = CountLikedArray(id: ICO.ICOId)
            if ind != -1 {
                ICOListLiked.remove(at: ind)
                lblLike.text = "Вы еще не лайкнули проект"
            }
        }
        if btnLike.isOn {
            let ind = CountLikedArray(id: ICO.ICOId)
            if ind == -1{
                ICOListLiked.append(self.ICO)
                lblLike.text = "Вам нравится проект"
            }
        }
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "del"), object: nil)
    }
    func FillButtonArray () {
        for value in ICO.news.values {
            var btn : CellProps!
            if value.lowercased().range(of:"t.me") != nil {
                btn = CellProps(image: #imageLiteral(resourceName: "telegram"), url: value)
            }
            else if value.lowercased().range(of:"bitcointalk.org") != nil {
                btn = CellProps(image: #imageLiteral(resourceName: "bitcoin"), url: value)
            } else {
                btn = CellProps(image: #imageLiteral(resourceName: "link"), url: value)
            }
            btnArray.append(btn)
        }
    }
    deinit {
        print("deinit detail")
    }

    override func viewDidDisappear(_ animated: Bool) {
        btnArray.removeAll()
        timer = nil
        outCollectioView = nil
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
extension DetailViewController: UICollectionViewDelegate, UICollectionViewDataSource, CollectionViewCellDelegate {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return btnArray.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let ICONs = btnArray[indexPath.row]
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
        cell.setCell(cell: ICONs)
        cell.delegate = self
        return cell
    }
    func didButtonClick(url: String) {
        let ICONURL = URL (string: url)!
         UIApplication.shared.open(ICONURL as URL)
    }
}

если я отлаживаю граф памяти, есть 3 DatailViewController и 18 CollectionViewCell


person Eugeny    schedule 23.10.2017    source источник
comment
начните с изменения ссылок на делегаты на weak: var delegate: CollectionViewCellDelegate! на ```` weak var delegate: CollectionViewCellDelegate!, and also remove notificationObserver```` везде, где это возможно.   -  person Mina    schedule 23.10.2017
comment
Также лучше вызывать timer.Invalidate() в viewDidDisappear   -  person Mina    schedule 23.10.2017
comment
уведомления наблюдают за необходимостью перезагрузки основного табличного представления, если в DetailViewController есть изменения   -  person Eugeny    schedule 23.10.2017
comment
добавьте : класс перед вашим протоколом: protocol CollectionViewCellDelegate: class {}   -  person Mina    schedule 23.10.2017
comment
я сделал это, делегат теперь слабый, но CollectionViewCell все еще в памяти, deinit не вызывается   -  person Eugeny    schedule 23.10.2017


Ответы (1)


Я нашел ленивый способ решить свою проблему, это

    outCollectioView.removeFromSuperview()
    btnLike.removeFromSuperview()

Но DetailViewController все еще увеличивается (((

person Eugeny    schedule 23.10.2017