thoughtbot / CombineViewModel

An implementation of the Model-View-ViewModel (MVVM) pattern using Combine.
MIT License
59 stars 4 forks source link

Avoid posting UIViewController.viewDidLoadNotification recursively #23

Closed sharplet closed 3 years ago

sharplet commented 3 years ago

When a UIViewController that does not override viewDidLoad() registers a @ViewModel property, the UIViewController implementation of viewDidLoad() is swizzled. When an unrelated class that does override viewDidLoad() registers a @ViewModel, it now has multiple swizzled implementations in its class hierarchy. The result is UIViewController.viewDidLoadNotification being posted multiple times for the same invocation of viewDidLoad() on a UIViewController subclass, once for each implementation of viewDidLoad() in the call stack.

Use an associated object to keep track of whether a viewDidLoad() implementation earlier in the stack is already planning to post the notification, so that recursive calls can check this property and skip posting duplicate notifications.

This maintains the desired property that UIViewController.viewDidLoadNotification is posted only once, after the most-derived viewDidLoad() implementation returns. It should guarantee that a given ViewModelObserver class has loaded all the views it knows about before accessing them in updateView().