Fix the subscription model for a balance screen

Review the AI's codeEasy10 minApple style

Your task

An AI wrote a view controller that subscribes to a shared Combine publisher in viewDidLoad and updates a balance label. It throws away the AnyCancellable that sink returns, and it captures self strongly. After a few visits, closed screens were still updating and duplicate network requests multiplied. Your team models the two fixes to see what each one stops.

An assistant wrote audit_subscription_leak(navigation_events, store_cancellable, weak_self), the model. It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • navigation_events: the log, in order. open shows a balance screen, which subscribes. close closes the most recently opened screen that is still open. emit is one new value from the shared publisher.
  • store_cancellable: each screen keeps its AnyCancellable and cancels it when the screen closes.
  • weak_self: the sink closure captures [weak self].
  • Return a list of two numbers: the upstream requests made, then the closed screens still held in memory.

Rules the tests check:

  • Ignore any other event, and ignore close when no screen is open.
  • Each emit makes one upstream request for every live subscription.
  • When a screen closes and store_cancellable is true, its subscription ends.
  • When a screen closes and store_cancellable is false, its subscription stays live and keeps making requests, whatever weak_self is.
  • A closed screen whose subscription is still live is held in memory, unless weak_self is true.

Examples

audit_subscription_leak(navigation_events: list[str], store_cancellable: bool, weak_self: bool) -> list[int]
Example 1
Inputaudit_subscription_leak(["open", "emit", "close", "open", "emit", "close", "open", "emit"], False, False)
Output[6, 2]
Example 2
Inputaudit_subscription_leak(["open", "emit", "close", "open", "emit", "close", "open", "emit"], True, False)
Output[3, 0]
Example 3
Inputaudit_subscription_leak(["open", "emit", "close", "open", "emit", "close", "open", "emit"], False, True)
Output[6, 0]