Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 调用Dislose后UIViewController仍在内存中_Ios_Swift - Fatal编程技术网

Ios 调用Dislose后UIViewController仍在内存中

Ios 调用Dislose后UIViewController仍在内存中,ios,swift,Ios,Swift,因此,我创建了一个UICollectionViewController类和一个自定义UICollectionViewCell。我在CollectionView中演示一个新的UIViewController,然后在UIViewController中取消它,以便返回CollectionView。除了在关闭UIViewController后,它仍然保留在内存中这不是我想要的以外,其他一切都正常工作。我想在UIViewController关闭后将其完全销毁,但无法确定如何进行销毁 我做错什么了吗?解除V

因此,我创建了一个UICollectionViewController类和一个自定义UICollectionViewCell。我在CollectionView中演示一个新的UIViewController,然后在UIViewController中取消它,以便返回CollectionView。除了在关闭UIViewController后,它仍然保留在内存中这不是我想要的以外,其他一切都正常工作。我想在UIViewController关闭后将其完全销毁,但无法确定如何进行销毁

我做错什么了吗?解除ViewController在解除后保留在内存中是否正常

// UICollectionViewController class
class MyCollection: UICollectionViewController, UICollectionViewDelegateFlowLayout { 

  let cellId = "cellId"

  override func viewDidLoad() {
    collectionView.register(CustomCell.self, forCellWithReuseIdentifier: cellId)
  }

  let viewControllers:[UIViewController] = [ViewController1()]

  override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    return viewControllers.count
  }   

  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let activityCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CustomCell

    return activityCell
  }    

  override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let vc = viewControllers[indexPath.item]

    present(vc, animated: true, completion: nil)
  }

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    return CGSize(width: view.frame.width, height: 90)
  }    
}

// Custom UICollectionViewCell class
class CustomCell: UICollectionViewCell {

  override init(frame: CGRect) {
    super.init(frame: frame)

    backgroundColor = .red
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

class ViewController1: UIViewController {

  lazy var dismissButton: UIButton = {
    let newButton = UIButton(type: .system)
    newButton.setTitle("Dismiss", for: .normal)
    newButton.backgroundColor = .red
    newButton.addTarget(self, action: #selector(dismissView), for: .touchUpInside)
    newButton.translatesAutoresizingMaskIntoConstraints = false
    return newButton
 }()   

 @objc func dismissView() {
   dismiss(animated: true, completion: nil)
 }

  override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(dismissButton)

    NSLayoutConstraint.activate([
      dissmissButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
      dissmissButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
      ])
  }
}

不,你没有做错。代码中没有强保留周期

唯一的问题是,即使关闭视图控制器,它仍然驻留在这里

let viewControllers:[UIViewController] = [ViewController1()]

如果希望实例被完全销毁,还需要将其从阵列中删除

为什么
ViewController1
实例没有完全销毁?

即使在
viewController
被解除之后,您仍然在
MyCollection的
viewControllers
数组中保留对它的引用

解决方案:

如果每次点击
单元格
,您都需要一个全新的
控制器实例,则无需将
控制器
存储在
视图控制器
数组

只需将
didSelectItemAt
方法更新为

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let vc = ViewController1() //here......
    present(vc, animated: true, completion: nil)
}

为viewController创建全局变量不是一个好的选择。如果您仍然持有它,您将无法销毁它。请按以下方式操作:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let vc:UIViewController?

        switch indexPath.row {
        case 0:
            vc = ViewController1()
        case 1:
            vc = ViewController2()
        default:
            vc = ViewController0()
        }
        present(vc!, animated: true, completion: nil)
    }
guard let nameSpace = Bundle.main.infoDictionary?["CFBundleName"] as? String else { return }
let clsName = String(format: "%@.%@", nameSpace, cList[indexPath.row])
let cls = (NSClassFromString(clsName) as? UIViewController.Type)!
let vc = cls.init()

present(vc, animated: true, completion: nil)
如果有许多ViewController,可能最好创建一个类数组,如下所示:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let vc:UIViewController?

        switch indexPath.row {
        case 0:
            vc = ViewController1()
        case 1:
            vc = ViewController2()
        default:
            vc = ViewController0()
        }
        present(vc!, animated: true, completion: nil)
    }
guard let nameSpace = Bundle.main.infoDictionary?["CFBundleName"] as? String else { return }
let clsName = String(format: "%@.%@", nameSpace, cList[indexPath.row])
let cls = (NSClassFromString(clsName) as? UIViewController.Type)!
let vc = cls.init()

present(vc, animated: true, completion: nil)
clist:
让clist=[“FirstController”,“SecondController”]

附言: 当然,如果我有50个ViewControllers,我就不会使用这条路线。我只是认为我们可以用最方便的方法来解决这个问题。
希望这会对你有所帮助。

为什么会破坏它?您在MyCollection的viewControllers数组中保留对每个控制器的引用。@PGDev让我感到不舒服的是在显示viewControllers前后内存的变化,我不明白为什么在演示后内存会增加,而在取消演示后内存会保持不变,但我想我现在明白了。如果你有50个ViewController,你还会这样做吗?无论哪种方法都给了你一个向上投票的机会,因为你向我展示了处理多个ViewController的另一种方法。