herzbube / littlego

Little Go. An iOS application that lets you play the game of Go on the iPhone or iPad.
https://littlego.herzbube.ch/
Apache License 2.0
138 stars 53 forks source link

Various crashes due to UI updates made in a secondary thread #364

Closed herzbube closed 3 years ago

herzbube commented 3 years ago

Because it is not thread-safe, UIKit in general wants updates to be performed on the main thread ([NSThread mainThread]). After releasing version 1.6.0 to the App Store, however, a number of new crashes were reported that all had the common cause that UI updates were performed in a secondary thread. Version 1.6.0 of the app was built with the iOS base SDK 14.3. Apparently iOS 14.3 has more checks that detect if UI updates are performed in a secondary thread, and these additional checks now let the app crash unconditionally more often. So while the crashes themselves are new, the underlying causes are not - older iOS versions simply did not detect the thread mismatches.

In the past thread mismatches were usually resolved by modifying the source of the UI update (e.g. a command) to perform the action that causes the UI update (e.g. sending a notification) on the main thread instead of on a secondary thread. The newest batch of crashes demonstrates that this approach is bound to fail:

A new approach is therefore to make sure that the receiver of a notification triggers the UI update on the main thread. Something along this line:

- (void) notificationHandler:(NSNotification*)notification
{
  if ([NSThread currentThread] == [NSThread mainThread])
    [self updateUI];
  else
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
}

- (void) updateUI
{
  [...]
}