简体   繁体   English

Memory Swift 中特定 ViewController 的问题 5

[英]Memory Problem with specific ViewController in Swift 5

I need some help with this problem.我需要一些帮助来解决这个问题。

I have this basic Scheme我有这个基本方案

  • HomeController家庭控制器
    • TripNavigation (view controller parent) TripNavigation(查看 controller 父级)
      • Step1 (view controller child) Step1(查看controller子)
      • Step2 (view controller child) Step2(查看controller子)

When i tap 10 times the button (buttonTapped) in homecontroller and then dismiss everytime.当我点击 10 次家庭控制器中的按钮 (buttonTapped) 然后每次都关闭。

  • In ui view hierarchy don't appear TripNavigation, which is good because i dismiss the controller and childs在 ui 视图层次结构中没有出现 TripNavigation,这很好,因为我忽略了 controller 和 childs
  • In View Memory Graph hierarchy:在 View Memory 图表层次结构中: 在此处输入图像描述

I think i create a cycle but i don't found it.我想我创造了一个循环,但我没有找到它。

My code:我的代码:

Home Controller:家庭电话 Controller:

class HomeController: UIViewController {
    
    var user: User?
    init(user: User) {
        self.user = user
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // show button on view
        
    }
    
    @objc func buttonTapped{
        DriverService.shared.observeTrip(uid: "XXX") { (userDB) in
            let controller = TripNavigation(user: userDB)
            controller.modalPresentationStyle = .fullScreen
            self.present(controller, animated: true, completion: nil)
        }
    }
    
}

TripNavigation code:旅行导航代码:

protocol TripProtocol: AnyObject {
    func userHasChanged(_ user: User?)
}
class TripNavigation: UIViewController {

    var user: User
    weak var delegate: TripProtocol?
    // array of childs
    var listOfSteps: [UIViewController] = []
    // segmented control to navigate in childs
    let mySegmentedControl: UISegmentedControl = {
        let sc = UISegmentedControl(items: ["1","2"])
        return sc
    }()
    
    init(user: User) {
        self.user = user
        super.init(nibName: nil, bundle: nil)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadviews()
        
        // here i make a addsubview for a button that call dissmisView() function (bottom of this class)
        // i call dissmisView to test if memory deallocated
        
    }

    func checkFirebaseNews(){
       // check new info from firebase and pass new data to childs
       self.delegate?.userHasChanged(user)
    }
    
    // main function that load the childs
    func loadviews(){
        
        mySegmentedControl.frame = CGRect(x: 0, y: 95, width: view.frame.width, height: 30)
        mySegmentedControl.addTarget(self, action: #selector(self.segmentedValueChanged(_:)), for: .valueChanged)
        view.addSubview(mySegmentedControl)
       
        // first child of TripNavigation
        let step1 = Step1(user: user, nextStep: 1)
        self.addChild(step1)
        step1.willMove(toParent: self)
        view.addSubview(step1.view)
        step1.didMove(toParent: self)
        step1.view.anchor(top:mySegmentedControl.topAnchor,left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 31)
        delegate = step1
        listOfSteps = [step1]
    
        // second child of TripNavigation
        let step2 = Step2(user: user, nextStep: -1)
        self.addChild(step2)
        step2.willMove(toParent: self)
        view.addSubview(step2.view)
        step2.didMove(toParent: self)
        step2.view.anchor(top:mySegmentedControl.topAnchor,left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 31)
        delegate = step2
        listOfSteps.append(step2)

        
        mySegmentedControl.selectedSegmentIndex = 0
        showView(num: 0)
        
        
    }
    
    // segmented control manage
    @objc func segmentedValueChanged(_ sender:UISegmentedControl!){

        switch sender.selectedSegmentIndex{
        case 0:
            
            showView(num: 0)
            
        case 1:
           
            showView(num: 1)

        default:
            break
        }
        
    }
    
    
    // aux functions
    func showView(num: Int){
        hideRestofViews(actual: num)
        let step = listOfSteps[num]
        step.view.isHidden = false
    }
    func hideRestofViews(actual: Int){
        if listOfSteps.count >= 1 {
            for (index, v) in listOfSteps.enumerated() {
                if index != actual{
                    v.view.isHidden = true
                }
            }
        }
    }
    
    
    
    
    @objc func dissmisView() {
      
        print("<W call to dismissview")
        for v in listOfSteps {
            v.willMove(toParent: nil)
            v.view.removeFromSuperview()
            v.removeFromParent()
            print(v)
            v.dismiss(animated: false, completion: nil)
            print("1")
        }
        
        print("<W all deleted")
        self.dismiss(animated: true, completion: nil)
        
    }
    
    // called in child, to change to other view child
    @objc func changeView(notification: NSNotification){
        
        if let next = notification.object as? Int {
            
            if next == -1{
                dissmisView()
            }else{
                mySegmentedControl.selectedSegmentIndex = next
                showView(num: next)
            }
            
        }
        
    }
    
    
}

Example of Step1 child code: Step1子代码示例:

// Step1 and Step2 are practically the same
class Step1: UIViewController,TripProtocol {

    var mapView = MKMapView()
    var user: User?
    var nextStep: Int
    
    func userHasChanged(_ user: User?) {
        self.user = user
    }
    
    
    init(user: User?, nextStep: Int) {
        self.user = user
        self.nextStep = nextStep
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        //configureMapView() ... configureUI... that show user data
        
    }
    
    @objc func nextStep(){
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "changeView"), object: nextStep)
    }
   
    
}

Thanks so much everyone!!非常感谢大家!!

EDIT @ROB HELP编辑@ROB帮助在此处输入图像描述

You can add the "TripNavigation" View Controllers to an array object in the HomeController then assign them to nil when dismissing them.您可以将“TripNavigation”视图控制器添加到 HomeController 中的数组 object,然后在关闭它们时将它们分配给 nil。

check this question: iOS view controller memory not released after it's been dismissed检查这个问题: iOS 查看 controller memory 在被解雇后未发布

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将用户重定向到特定的ViewController - Swift 4 - Redirect User to Specific ViewController - Swift 4 将数据发送到另一个 ViewController 的 Swift 问题 - Swift problem with sending data to another ViewController swift-如何检查特定的viewController是否为先前的viewController - swift - how can i check if a specific viewController is the previous viewController 在推送通知Swift 2 AppDelegate上加载特定的viewController - Load a specific viewController on push notification Swift 2 AppDelegate 将.swift中的全局变量传递给特定的viewController - Passing global variables in .swift to specific viewController 在单个 ViewController 应用程序中内存保留周期是不可能的吗? (斯威夫特/IOS) - Are memory retain cycles impossible in a single-ViewController-app? (Swift / IOS) 关于Swift在一个viewController中创建多个collectionView问题的问题 - Question about the problem of creating multiple collectionView in one viewController in Swift 如何解决在 Swift 中通过 Coordinator 的操作打开 ViewController 的问题? - How to fix problem with opening ViewController by action from Coordinator in Swift? 当应用程序在 swift 3 中处于前台时隐藏特定视图控制器的远程通知 - Hide remote notification at specific viewcontroller when app is in foreground in swift 3 如何在Swift中单击UILocalNotification时如何启动特定的ViewController - How Do You Launch A Specific ViewController When UILocalNotification Is Clicked In Swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM