iOS app freezes after dismiss view in swift
Asked Answered
W

3

10

My issue is this I have two viewControllers connected with a modal segue like normal A--->B, A has the controls like textFields, switches, buttons and a mapView where I get the userLocation. B hast only a button, and a mapView at the moment, but when I tap the exit button it does successfully dismisses viewController B and shows A only controls are frozen, can't tap anything anymore, I don't know why. Any help?

B code

import UIKit
import MapKit
import Parse
import CoreLocation

class MapaMososViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    @IBOutlet weak var mapMozosFollow: MKMapView!

    var totlaAutomozo: String!
    var fechaRegistro: String!


    override func viewDidLoad() {
        super.viewDidLoad()


        mapMozosFollow.delegate = self

        mapMozosFollow.showsUserLocation = true
        mapMozosFollow.showsTraffic = false
        mapMozosFollow.showsScale = false
        print(mapMozosFollow.userLocation.location)


    }

    override func viewDidAppear(_ animated: Bool) {

        self.displayError(error: "Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totlaAutomozo!) la fecha registrada \(fechaRegistro!)")

    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


    override func viewWillDisappear(_ animated: Bool) {

    }
    @IBAction func salirTapped(_ sender: UIButton) {


            self.dismiss(animated: true, completion: {

                print("here dismissing")
            })



    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        print(locations.last!.coordinate)
        centerMapOnLocation(locations.last!)
    }
    let regionRadius: CLLocationDistance = 2000

    func centerMapOnLocation(_ location: CLLocation) {
        let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
                                                                  regionRadius * 2.0, regionRadius * 2.0)
        mapMozosFollow.setRegion(coordinateRegion, animated: true)
    }



}

EDIT 1: A ViewController code.

import UIKit
import Parse
import MapKit
import BraintreeDropIn
import Braintree

class ViewController: UIViewController, PayPalPaymentDelegate, PayPalFuturePaymentDelegate, PayPalProfileSharingDelegate, CLLocationManagerDelegate, UITextFieldDelegate, MKMapViewDelegate, BTDropInViewControllerDelegate {


    @IBOutlet weak var scrollView: UIScrollView!

    @IBOutlet weak var mapaLugar: MKMapView!
    @IBOutlet weak var numeroExteriorTextField: UITextField!
    @IBOutlet weak var telefonoTextField: UITextField!


    @IBOutlet weak var lavadoSwitch: UISwitch!
    @IBOutlet weak var lavadoYAspiradSwitch: UISwitch!


    @IBOutlet weak var numeroCarrosTextField: UITextField!
    @IBOutlet weak var numeroMinivanTextField: UITextField!
    @IBOutlet weak var numeroPickUpsTextField: UITextField!
    @IBOutlet weak var numeroVansTextField: UITextField!


    @IBOutlet weak var numeroAspiradoCarrosTextField: UITextField!
    @IBOutlet weak var numeroAspiradoMinivanTextField: UITextField!
    @IBOutlet weak var numeroAspiradoPickUpsTextField: UITextField!
    @IBOutlet weak var numeroAspiradoVansTextField: UITextField!


    @IBOutlet weak var botonRealizarPedido: UIButton!
    @IBOutlet weak var botonInstrucciones: UIButton!


    @IBOutlet weak var totalLabel: UILabel!

    var showAlertFirstTime: Bool = true

    var locationManager: CLLocationManager = CLLocationManager()
    var ubicacion: CLLocationCoordinate2D!

    var environment:String = PayPalEnvironmentSandbox {
        willSet(newEnvironment) {
            if (newEnvironment != environment) {
                PayPalMobile.preconnect(withEnvironment: newEnvironment)
            }
        }
    }

    var braintreeClient: BTAPIClient?

    let defaults = UserDefaults.standard

    var resultText = "" // empty
    var payPalConfig = PayPalConfiguration() // default

    var total: NSDecimalNumber!

    var vistaDeMozos: Bool = false


    var fechaRegistro: String!
    var totalToSend: String!


    @IBOutlet weak var constrainSizeMap: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()

        botonInstrucciones.backgroundColor = UIColor(colorLiteralRed: (200.0/255.0), green: 0.0, blue: 0.0, alpha: 1.0)
        botonInstrucciones.layer.cornerRadius = 3
        botonInstrucciones.layer.borderWidth = 2
        botonInstrucciones.layer.borderColor = UIColor.clear.cgColor
        botonInstrucciones.layer.shadowColor = UIColor(colorLiteralRed: (100.0/255.0), green: 0.0, blue: 0.0, alpha: 1.0).cgColor
        botonInstrucciones.layer.shadowOpacity = 1.0
        botonInstrucciones.layer.shadowRadius = 1.0
        botonInstrucciones.layer.shadowOffset = CGSize(width: 0, height: 3)


        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.requestAlwaysAuthorization()

        self.locationManager.startUpdatingLocation()

        NotificationCenter.default.post(name: Notification.Name(rawValue: "keyPressed"), object: nil)

        numeroCarrosTextField.delegate = self
        numeroMinivanTextField.delegate = self
        numeroPickUpsTextField.delegate = self
        numeroVansTextField.delegate = self

        numeroAspiradoCarrosTextField.delegate = self
        numeroAspiradoMinivanTextField.delegate = self
        numeroAspiradoPickUpsTextField.delegate = self
        numeroAspiradoVansTextField.delegate = self

        do {

            if defaults.object(forKey: "clientId") == nil || clientId == "000" {

                let idTest = try PFCloud.callFunction("newCutomer", withParameters: nil)
                print(idTest)
                clientId = idTest as! String
                defaults.set(clientId, forKey: "clientId")

            } else {

                print(self.clientId)
            }

        } catch let error {

            print(error)
        }

        if defaults.object(forKey: "clientId") == nil {

        } else {

            clientId = defaults.string(forKey: "clientId")!
            print(clientId)
        }


       fetchClientToken()


        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ViewController.keyboardWillShow(notification:)),
            name: NSNotification.Name.UIKeyboardWillShow,
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(ViewController.keyboardWillHide(notification:)),
            name: NSNotification.Name.UIKeyboardWillHide,
            object: nil
        )

        scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.interactive

        let touch = UITapGestureRecognizer(target: self, action: #selector(ViewController.singleTapGestureCaptured(gesture:)))
        scrollView.addGestureRecognizer(touch)

    }

    func singleTapGestureCaptured(gesture: UITapGestureRecognizer){
        self.view.endEditing(true)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        if showAlertFirstTime {


            showAlertFirstTime = false
        } else {

        }
      }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        PayPalMobile.preconnect(withEnvironment: environment)

        print("stop test")

    } 
    @IBAction func realizarPedidoTapped(_ sender: UIButton) {


        let numeroExterior = numeroExteriorTextField.text!
        let numeroMotosLavado = numeroCarrosTextField.text!
        let numeroDeportivosLavado = numeroMinivanTextField.text!
        let numeroCarroLavado = numeroPickUpsTextField.text!
        let numeroCamionLavado = numeroVansTextField.text!
        let numeroMotoLavadoAspirado = numeroAspiradoCarrosTextField.text!
        let numeroDeportivoLavadoAspirado = numeroAspiradoMinivanTextField.text!
        let numeroCarroLavadoAspirado = numeroAspiradoPickUpsTextField.text!
        let numeroCamionLavadoAspirado = numeroAspiradoVansTextField.text!
        let numeroTelefono = telefonoTextField.text!

        if numeroExterior == "" || numeroTelefono == "" {


            displayError("Error", message: "Te falto llenar tu numero exterior y/o telefono")

        } else {

            //Braintree init
            self.braintreeClient = BTAPIClient(authorization: clientToken)



        let items = [item1]
        let subtotal = PayPalItem.totalPrice(forItems: items)

        //var subtotal = PayPalItem.totalPrice(forItems: items)
        let shipping = NSDecimalNumber(string: "0.00")
        let tax = NSDecimalNumber(string: "0.00")

        //details ???

        let paymentDetails = PayPalPaymentDetails(subtotal: subtotal, withShipping: shipping, withTax: tax)

        self.total = subtotal.adding(shipping).adding(tax)

        let payment = PayPalPayment(amount: total, currencyCode: "MXN", shortDescription: "Automozo inc", intent: .sale)

        payment.items = items
        payment.paymentDetails = paymentDetails

        print("\(payment.localizedAmountForDisplay)")


        self.showDropIn(clientTokenOrTokenizationKey: clientToken)

        if (payment.processable) {

            let paymentViewController = PayPalPaymentViewController(payment: payment, configuration: payPalConfig, delegate: self)

        }
        else {

            print("Payment not processalbe: \(payment.description)")
            print("payment not processable \(payment)")

            displayError("Error", message: "Hubo un error al procesar tu pago, por favor intenta de nuevo.")

            }
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        super.prepare(for: segue, sender: sender)
        if segue.identifier == "MapaMozosSegue" {

            let mapaMozosVC = segue.destination as! MapaMososViewController
            mapaMozosVC.totlaAutomozo = totalToSend!
            mapaMozosVC.fechaRegistro = fechaRegistro
            locationManager.stopUpdatingLocation()
        }
    }

    func textFieldDidEndEditing(_ textField: UITextField) {

        textField.resignFirstResponder()
        print("test text field ended")

        if textField.text == "" {

            textField.text = "0"
        }

        var numeroCarrosLavadoVar = numeroCarrosTextField.text!
        var numeroMinivansLavadoVar = numeroMinivanTextField.text!
        var numeroPickUpsLavadoVar = numeroPickUpsTextField.text!
        var numeroVansLavadoVar = numeroVansTextField.text!

        var numeroCarrosLavadoAspiradoVar = numeroAspiradoCarrosTextField.text!
        var numeroMinivansLavadoAspiradoVar = numeroAspiradoMinivanTextField.text!
        var numeroPickUpsLavadoAspiradoVar = numeroAspiradoPickUpsTextField.text!
        var numeroVansLavadoAspiradoVar = numeroAspiradoVansTextField.text!

        if numeroCarrosLavadoVar == "" {
            numeroCarrosLavadoVar = "0"
            numeroCarrosTextField.text = "0"
        }
        if numeroMinivansLavadoVar == "" {
            numeroMinivansLavadoVar = "0"
            numeroMinivanTextField.text = "0"

        }
        if numeroPickUpsLavadoVar == "" {
            numeroPickUpsLavadoVar = "0"
            numeroPickUpsTextField.text = "0"
        }
        if numeroVansLavadoVar == "" {
            numeroVansLavadoVar = "0"
            numeroVansTextField.text = "0"

        }
        if numeroCarrosLavadoAspiradoVar == "" {
            numeroCarrosLavadoAspiradoVar = "0"
            numeroAspiradoCarrosTextField.text = "0"
        }
        if numeroMinivansLavadoAspiradoVar == "" {
            numeroMinivansLavadoAspiradoVar = "0"
            numeroMinivanTextField.text = "0"

        }
        if numeroPickUpsLavadoAspiradoVar == "" {
            numeroPickUpsLavadoAspiradoVar = "0"
            numeroAspiradoPickUpsTextField.text = "0"
        }
        if numeroVansLavadoAspiradoVar == "" {
            numeroVansLavadoAspiradoVar = "0"
            numeroVansTextField.text = "0"


        }

        let priceOfLavadoCarro = Int(numeroCarrosLavadoVar)! * pricesLavado["LavadoCarro"]!
        let priceOfLavadoMinivan = Int(numeroMinivansLavadoVar)! * pricesLavado["LavadoMinivan"]!
        let priceOfLavadoPickUp = Int(numeroPickUpsLavadoVar)! * pricesLavado["LavadoPickUp"]!
        let priceOfLavadoVan = Int(numeroVansLavadoVar)! * pricesLavado["LavadoVan"]!

        //Lavado y Aspirado

        let priceOfLavadoYAspiradoCarro = Int(numeroCarrosLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoCarro"]!
        let priceOfLavadoYAspiradoMinivan = Int(numeroMinivansLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoMinivan"]!
        let priceOfLavadoYAspiradoPickUp = Int(numeroPickUpsLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoPickUp"]!
        let priceOfLavadoYAspiradoVan = Int(numeroVansLavadoAspiradoVar)! * pricesLavadoYAspirado["LavadoYAspiradoVan"]!

        let totalAutomozo = priceOfLavadoCarro + priceOfLavadoMinivan + priceOfLavadoPickUp + priceOfLavadoVan + priceOfLavadoYAspiradoCarro + priceOfLavadoYAspiradoMinivan + priceOfLavadoYAspiradoPickUp + priceOfLavadoYAspiradoVan

        print(totalAutomozo)

        totalLabel.text = "\(totalAutomozo).00"

        textField.resignFirstResponder()
    }

    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {

        if (textField.text?.characters.count)! == 1 {

            print("text quota meet")
            textField.resignFirstResponder()
            self.view.endEditing(true)

            return true

        } else {

            textField.text = "0"
        }

        return true
    }


    let regionRadius: CLLocationDistance = 100

    func centerMapOnLocation(_ location: CLLocation) {
        let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
                                                                  regionRadius * 2.0, regionRadius * 2.0)
        mapaLugar.setRegion(coordinateRegion, animated: true)
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        centerMapOnLocation(locations.last!)
        ubicacion = locations.last!.coordinate

   }
    // Mark - Braintree methods

    func showDropIn(clientTokenOrTokenizationKey: String) {

        var value: Bool = false
        var totlaAutomozo = self.totalLabel.text

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMM dd YYYY HH:mm"
        dateFormatter.timeZone = NSTimeZone.local


        fechaRegistro = dateFormatter.string(from: Date())

        let request =  BTDropInRequest()
        request.amount = "\(total)"
        request.currencyCode = "MXN"
        print(request.description)
        BTUIKAppearance.darkTheme()
        BTUIKAppearance.sharedInstance().activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
//            request.
        let dropIn = BTDropInController(authorization: clientTokenOrTokenizationKey, request: request)
        { (controller, result, error) in
            if (error != nil) {
                print("ERROR")
            } else if (result?.isCancelled == true) {
                print("CANCELLED")
            } else if let result = result {
                // Use the BTDropInResult properties to update your UI




                print(result.paymentOptionType)
                print("payment method: \(result.paymentMethod?.nonce)")
                print("ppayment desc \(result.paymentDescription)")
                print(result.paymentIcon.description)

                value = self.postNonceToServer(paymentMethodNonce: (result.paymentMethod?.nonce)!)


                }
                controller.dismiss(animated: true, completion: nil)


                if value {

                    self.locationManager.stopUpdatingLocation()

                    self.performSegue(withIdentifier: "MapaMozosSegue", sender: self)

                    self.vistaDeMozos = true

                } else {

                    self.displayError("Alerta", message: "El pedido ha sido cancelado exitosamente.")

                    //top row
                    self.numeroCarrosTextField.text = "0"
                    self.numeroMinivanTextField.text = "0"
                    self.numeroPickUpsTextField.text = "0"
                    self.numeroVansTextField.text = "0"

                    //bottom row
                    self.numeroAspiradoCarrosTextField.text = "0"
                    self.numeroAspiradoMinivanTextField.text = "0"
                    self.numeroAspiradoPickUpsTextField.text = "0"
                    self.numeroAspiradoVansTextField.text = "0"

                    //data
                    self.telefonoTextField.text = ""
                    self.telefonoTextField.text = ""
                }
            }
            self.present(dropIn!, animated: true, completion: nil)

    }

    func userDidCancelPayment() {
        self.dismiss(animated: true, completion: nil)
    }

    func postNonceToServer(paymentMethodNonce: String) -> Bool {

        var val = true

        do {
            var response = try PFCloud.callFunction("checkout", withParameters: ["payment_method_nonce":paymentMethodNonce, "amount":"\(total!).00", "customerId": clientId])
            print(response)

        } catch let error {

            print(error.localizedDescription)
        }

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMM. dd, YYYY HH:mm"
        dateFormatter.timeZone = NSTimeZone.local

        fechaRegistro = dateFormatter.string(from: Date())


        let usuarioPagado: PFObject = PFObject(className: "Ordenes")
        let location: PFGeoPoint = PFGeoPoint(latitude: ubicacion.latitude, longitude: ubicacion.longitude)
        usuarioPagado["Ubicacion"] = location
        usuarioPagado["NumeroExterior"] = numeroExteriorTextField.text!
        usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text!
        usuarioPagado["LavadoCarro"] = numeroCarrosTextField.text!
        usuarioPagado["LavadoMiniVan"] = numeroMinivanTextField.text!
        usuarioPagado["LavadoPickUp"] = numeroPickUpsTextField.text!
        usuarioPagado["LavadoDeVan"] = numeroVansTextField.text!
        usuarioPagado["LavadoAspiradoCarro"] = numeroAspiradoCarrosTextField.text!
        usuarioPagado["LavadoAspiradoMiniVan"] = numeroAspiradoMinivanTextField.text!
        usuarioPagado["LavadoAspiradoPickUp"] = numeroAspiradoPickUpsTextField.text!
        usuarioPagado["LavadoAspiradoDeVan"] = numeroAspiradoVansTextField.text!
        usuarioPagado["Monto"] = totalLabel.text!
        usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text!
        usuarioPagado["TipoDeCelular"] = "iPhone"
        usuarioPagado["FechaDeOrden"] = fechaRegistro

        self.totalToSend = self.totalLabel.text!

                usuarioPagado.saveInBackground() {
                    (success: Bool, error: Error?) -> Void in

                    if error == nil {

                        //done
                        print("saved object")
                        val = false

                    } else {

                        //not done
                        print("not saved because \(error?.localizedDescription)")

                    }
                }

        numeroCarrosTextField.text = "0"
        numeroMinivanTextField.text = "0"
        numeroPickUpsTextField.text = "0"
        numeroVansTextField.text = "0"

        numeroAspiradoCarrosTextField.text = "0"
        numeroAspiradoMinivanTextField.text = "0"
        numeroAspiradoPickUpsTextField.text = "0"
        numeroAspiradoVansTextField.text = "0"
        totalLabel.text = "00.00"
        self.lavadoSwitch.isOn = false
        self.lavadoYAspiradSwitch.isOn = false

        self.numeroExteriorTextField.text = ""
        self.telefonoTextField.text = ""

        self.numeroCarrosTextField.isHidden = true
        self.numeroMinivanTextField.isHidden = true
        self.numeroPickUpsTextField.isHidden = true
        self.numeroVansTextField.isHidden = true

        self.numeroAspiradoCarrosTextField.isHidden = true
        self.numeroAspiradoMinivanTextField.isHidden = true
        self.numeroAspiradoPickUpsTextField.isHidden = true
        self.numeroAspiradoVansTextField.isHidden = true
    return val

    }

    func drop(inViewControllerDidLoad viewController: BTDropInViewController) {

        print("did load view drop")

    }

    func drop(inViewControllerDidCancel viewController: BTDropInViewController) {

        print("did cancel drop payment")

    }

    func drop(inViewControllerWillComplete viewController: BTDropInViewController) {

        print("drop will complete payment")

    }

    func drop(_ viewController: BTDropInViewController, didSucceedWithTokenization paymentMethodNonce: BTPaymentMethodNonce) {

        var totlaAutomozo = totalLabel.text

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMM dd YYYY HH:mm"
        dateFormatter.timeZone = NSTimeZone.local


        fechaRegistro = dateFormatter.string(from: Date())

        print("did succeeded with tokenization")
        print(" \(paymentMethodNonce.nonce)")

        var value = postNonceToServer(paymentMethodNonce: paymentMethodNonce.nonce)



        self.dismiss(animated: true, completion: nil)


        if value {

            displayError("Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totlaAutomozo ?? "00.00") la fecha registrada \(fechaRegistro)")


        } else {

            self.displayError("Error", message: "Hubo un error al guardar tu informacion, ponte en contacto con nosotros.")
        }

    }

    func fetchClientToken() {

        do {

            let response = try PFCloud.callFunction("generateToken", withParameters: ["clientId": clientId])
           self.clientToken = response as! String



        } catch let error {

            print(error)
        }
    }

    func keyboardWillShow(notification:NSNotification){

        var userInfo = notification.userInfo!
        var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        keyboardFrame = self.view.convert(keyboardFrame, from: nil)

        var contentInset:UIEdgeInsets = self.scrollView.contentInset
        contentInset.bottom = keyboardFrame.size.height
        self.scrollView.contentInset = contentInset
    }

    func keyboardWillHide(notification:NSNotification){

        let contentInset:UIEdgeInsets = UIEdgeInsets.zero
        self.scrollView.contentInset = contentInset
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        self.view.endEditing(true)

    }

    func showFullMap() {


        if vistaDeMozos {

            self.telefonoTextField.isHidden = true
            self.botonRealizarPedido.isHidden = true
            self.lavadoSwitch.isHidden = true
            self.lavadoYAspiradSwitch.isHidden = true
            self.botonRealizarPedido.isHidden = true

            self.numeroExteriorTextField.isHidden = true

            self.numeroCarrosTextField.isHidden = true
            self.numeroMinivanTextField.isHidden = true
            self.numeroPickUpsTextField.isHidden = true
            self.numeroVansTextField.isHidden = true


            self.numeroAspiradoCarrosTextField.isHidden = true
            self.numeroAspiradoMinivanTextField.isHidden = true
            self.numeroAspiradoPickUpsTextField.isHidden = true
            self.numeroAspiradoVansTextField.isHidden = true

            self.view.layoutSubviews()
        } else {


        }
    }
}
Welkin answered 26/1, 2017 at 0:15 Comment(3)
check if your deinit method is called and that your viewcontroller is released succesfully when you are dismissing first. deinit { // check here } if it does, then the problem may be in your A viewcontroller, which is not posted.Aerobiology
In "B code" don't forget to call the super implementations in the viewDidAppear, viewWillDisappear. Maybe it can also resolve your issue.Airline
Likely related: https://mcmap.net/q/362316/-warning-output-of-vertex-shader-39-v_gradient-39-not-read-by-fragment-shaderLashondalashonde
M
20

Did you try pausing the app with the debugger to inspect the stack frames? Sometimes that can help you spot deadlocks or infinite loops. You'll find the pause button in the bar between the code editor and the debugger (or at the bottom if the debugger is hidden):

Pause

Look at the stack frames in the Debug Navigator on the left-hand side of the Xcode window. Can you see anything suspicious? Here is a stack frame that indicates the app is idling on the main run loop:

Idling

That's usually perfectly normal as the app is waiting for user input. If you see something like the following you are likely dealing with a deadlock:

Deadlock

The semaphore stops the thread from continuing until some other thread opens the semaphore again. You are dealing with a deadlock if two or more threads are stopped waiting for each other. If the main thread is involved the app will be frozen.

The third possibility I can think of is an infinite loop on the main thread:

Infinite loop

Of course this one is pretty easy to spot :) The darker entries in stack frames are from your own code. You can click on those entries to find the exact locations and use the debugger to inspect variables. The other entries will show you assembly.

If you could not find anything suspicious by pausing the debugger I would start to remove those parts of code bit by bit, trying to reproduce the problem each time. There are two possible results:

  1. You remove some harmless looking code and suddenly it works as expected. You can then take a closer look at the code you removed, making it easier to figure the issue out.

  2. You end up with a minimal project exhibiting the issue. This is now much easier to debug and reason about because there is nothing else distracting you from the problem. You also have a much higher probability of getting help from coworkers or here on Stack Overflow when your code sample is as small as possible.

A third attack vector is checking the View Debugger:

  1. Are there any transparent views above the frozen view controller blocking user events?

  2. Is user interaction enabled on the controls and views involved? Select a view and check the Object Inspector on the right-hand side:

enter image description here

Microcosm answered 28/1, 2017 at 20:21 Comment(3)
Yes I have a deadlock, I can see the semaphore_wait_trap () is ther a way to know where I'm getting it?Welkin
Check if you see anything that helps in the other running threads. See if you can deduce any information from the trace of the blocked thread. This can be hard detective work. If nothing helps, reduce the project to the bare minimum as I suggested and post another question.Microcosm
I would start by commenting out viewWillAppear in A, but that's just a hunch...Microcosm
B
2

Try to remove DispatchQueue.main.async or the A viewController won't get notified. It's interaction has been disabled because the segue

//DispatchQueue.main.async {
  self.dismiss(animated: true, completion: {
    print("here dismissing")
  })
//}
Birck answered 26/1, 2017 at 2:27 Comment(1)
Done I have changed to that ti didn't help, I saw something weird happening . After dismissing the VC B it returns to A goes self.dismiss(animated: true, completion: { print("here dismissing") }) does that and returns to B to do the completion how come?Welkin
C
1

Make sure to check if any NSDelayedPerforming methods are blocking the main thread (Foundation > NSRunloop). i.e. performSelector afterDelay...

In my case (Objective-C) I had to use cancelPreviousPerformRequestsWithTarget in the viewDidDisappear instance method of the ViewController.

[NSObject cancelPreviousPerformRequestsWithTarget:self];

I think the same applies when using NSTimer.scheduledTimerWithTimeInterval (Swift) without invalidating the timer in the proper life cycle method.

Celt answered 4/7, 2017 at 23:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.