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