Fix the cost model for SwiftUI thumbnails

Review the AI's codeEasy10 minApple style

Your task

An AI wrote a SwiftUI thumbnail that downloads and downsamples its photo inside body. SwiftUI runs body on the main thread on every layout pass, so scrolling stuttered, and the launch watchdog sometimes killed the app. The fix moves loading into an async loader with a cache. Your team models the cost of both versions.

An assistant wrote main_thread_render_cost(cell_urls, layout_passes, load_ms, decode_ms, work_in_body, watchdog_limit_ms), the model. It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • cell_urls: the photo URL of each cell in the grid. Several cells can show the same URL.
  • layout_passes: how many times the grid lays out.
  • load_ms and decode_ms: the cost of one read and of one downsample, in ms.
  • work_in_body: true for the original, false for the async loader with a cache.
  • watchdog_limit_ms: the main thread time at which the system kills the app.
  • Return a list of three numbers: main thread ms, loads performed, and 1 if the watchdog fires or 0 if not.

Rules the tests check:

  • If layout_passes is 0 or less, or there are no cells, return [0, 0, 0].
  • The cost of one load is load_ms + decode_ms, or 0 if that sum is negative.
  • With work_in_body true, every cell loads its photo on every layout pass, on the main thread. Loads performed is the number of those loads, and main thread ms is that number times the cost of one load.
  • With work_in_body false, main thread ms is 0, and each distinct URL is loaded exactly once, however many cells or passes show it.
  • The watchdog fires when watchdog_limit_ms is greater than 0 and main thread ms is at least watchdog_limit_ms.

Examples

main_thread_render_cost(cell_urls: list[str], layout_passes: int, load_ms: int, decode_ms: int, work_in_body: bool, watchdog_limit_ms: int) -> list[int]
Example 1
Inputmain_thread_render_cost(["a.jpg", "b.jpg", "c.jpg"], 3, 40, 25, True, 5000)
Output[585, 9, 0]
Example 2
Inputmain_thread_render_cost(["a.jpg", "b.jpg", "c.jpg"], 3, 40, 25, False, 5000)
Output[0, 3, 0]
Example 3
Inputmain_thread_render_cost(["a.jpg"], 1, 3000, 2000, True, 5000)
Output[5000, 1, 1]