0

My users experienced crashes when I sent them an update on TestFlight. After examining the eight crash reports they submitted, I've noticed a commonality - there are two of the same closures sitting on top of thread 0. Could this have caused the crash? What do you think is the cause, if not?

Please see image for crash report of thread 0. All other threads generally look the same in the report.

Note - when the users opened their app subsequent times after the initial opening, they did not experience further crashes.

Thank you in advance for your thoughts.

Update from comments, 9/29/22 -

Here's the closure code as requested by Damien and Tadreik:

When the app is opened, this line runs during initialization, which sets up the variables the connection view controller needs. Thus the empty closure.

if !twilioIDs.isEmpty { 
    ProfileModelManager.shared.getUsersForConnectionView(withTwilioIDs: twilioIDs) { _ in }
}

And the code below is invoked when the connection view is tapped on from the menu tab the second time:

if !twilioIDs.isEmpty {
    ProfileModelManager.shared.getUsersForConnectionView(withTwilioIDs: twilioIDs) { result in
        guard let success = result else { return }
            
        if success {
            self.handleSuccessOfGettingConnectionCards()
        }
        else {
            self.handleFailureOfGettingConnectionCards()
        }
    } 
}

Here is the code for handleSuccessOfGettingConnectionCards -

refreshControl.endRefreshing()
hideNoConnectionsLabel()
createChatViewControllersForChannels()
connectionsTableView.alpha = 1
errorConnectingLabel.alpha = 0
connectionsTableView.reloadData()
showActivitySpinner(false)
navigationController?.navigationBar.isHidden = true

Here is the code for handleFailureOfGettingConnectionCards -

showErrorConnectingMessage()
refreshControl.endRefreshing()
connectionsTableView.alpha = 0
hideNoConnectionsLabel()
showActivitySpinner(false)

Thanks in advance again for any intuition or experience you may share.

The crash log for thread 0

  • Is there anything than can trigger an exception in that closure ? – Damien Sep 28 '22 at 22:13
  • The stack trace shows two different lines in that closure. The first line listed is where the exception occurred or was reported (do you have a `catch` clause or something that throws an exception?) the second line is the point of execution before the exception occurred and so on; it is the *call stack trace*. You should symbolicate the crash log and identify the actual lines involved. – Paulw11 Sep 28 '22 at 22:47
  • Hi Damien and Paulw11 - nothing in the involved code throws an exception. Mystery is - why does it work fine after the initial loading of the new version from TestFlight? It's confusing to me. Paulw11 - do you have any resources for symbolicating in Xcode? Do ya'll think it could be some strange race condition? – lizardcoder Sep 29 '22 at 02:54
  • Can you paste the closure code in your question please ? – Damien Sep 29 '22 at 11:12
  • Looks like you're not handling concurrency properly. Post your code – Tad Sep 29 '22 at 13:16
  • Paulw11 - thanks for the pro tip about symbolicating. I'm digging into it, and I'm sure it'll provide some insights. – lizardcoder Sep 30 '22 at 01:28

1 Answers1

0

The code inside the closure ProfileModelManager.shared.getUsersForConnectionView(withTwilioIDs: twilioIDs) { result in captures a reference to self, your problem might be that at the time of execution, self is pointing to a null reference (has been deallocated), which can cause a crash. Try to set a weak reference to self like that and see if the crash still occurs :

if !twilioIDs.isEmpty {
    ProfileModelManager.shared.getUsersForConnectionView(withTwilioIDs: twilioIDs) { [weak self] result in
        guard let success = result else { return }
            
        if success {
            self?.handleSuccessOfGettingConnectionCards()
        }
        else {
            self?.handleFailureOfGettingConnectionCards()
        }
    } 
}

If you want you could also handle the nil case of the weak self as any other optional.

Damien
  • 3,322
  • 3
  • 19
  • 29
  • Thanks for this, Damien. After looking at the symbolicated crash report, and reading some more, this appears to be the way to prevent these crashes. Do you suspect it would matter for the empty closure? – lizardcoder Sep 30 '22 at 23:57
  • Nothing to worry for the empty closure, as you are not trying to access self at a time when it's deallocated. – Damien Oct 01 '22 at 00:01
  • If the answer I provided is the right one and can help others in your situation, feel free to accept it so it appears with the check mark ;) – Damien Oct 01 '22 at 00:02
  • Done and done . – lizardcoder Oct 01 '22 at 00:10