{"id":48170,"date":"2025-06-20T16:40:32","date_gmt":"2025-06-20T20:40:32","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=48170"},"modified":"2025-06-26T11:09:42","modified_gmt":"2025-06-26T15:09:42","slug":"subtle-swift-retain-cycle","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2025\/06\/20\/subtle-swift-retain-cycle\/","title":{"rendered":"Subtle Swift Retain Cycle"},"content":{"rendered":"<p><a href=\"https:\/\/paul-samuels.com\/blog\/2025\/06\/19\/subtle-retain-cycle-is-subtle\/\">Paul Samuels<\/a>:<\/p>\n<blockquote cite=\"https:\/\/paul-samuels.com\/blog\/2025\/06\/19\/subtle-retain-cycle-is-subtle\/\">\n<p>The problem we have looking at the scope is that the strong reference is in scope until the end of the function, but we have our <code class=\"language-plaintext highlighter-rouge\">repeat<\/code> loop before the end of the function so we will never get to the end.<\/p>\n<p>[&#8230;]<\/p>\n<p>You could write a unit to verify that the reference does not leak something like <a href=\"https:\/\/paul-samuels.com\/blog\/2018\/11\/20\/unit-testing-retain-cycles\">this<\/a>.<\/p>\n<\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/08\/17\/how-to-automate-memory-leak-detection-with-xctest\/\">How to Automate Memory Leak Detection With XCTest<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/08\/04\/avoiding-implicit-retain-cycles-when-using-swift-function-references\/\">Avoiding Implicit Retain Cycles When Using Swift Function References<\/a><\/li>\n<\/ul>\n\n<p id=\"subtle-swift-retain-cycle-update-2025-06-26\">Update (<a href=\"#subtle-swift-retain-cycle-update-2025-06-26\">2025-06-26<\/a>): <a href=\"https:\/\/bsky.app\/profile\/bolsinga.com\/post\/3lsezmhf7lc23\">Greg Bolsinga<\/a>:<\/p>\n<blockquote cite=\"https:\/\/bsky.app\/profile\/bolsinga.com\/post\/3lsezmhf7lc23\">\n<p>Beside other issues, the code here does work before seeing if the <code>Task<\/code> is cancelled. This is contrary to <a href=\"https:\/\/docs.swift.org\/swift-book\/documentation\/the-swift-programming-language\/concurrency\/#:~:text=Each%20task%20checks%20for%20cancellation%20before%20starting%20to%20download%20the%20photo.%20If%20it%20has%20been%20canceled%2C%20the%20task%20returns%20nil\">the documentation<\/a>.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Paul Samuels: The problem we have looking at the scope is that the strong reference is in scope until the end of the function, but we have our repeat loop before the end of the function so we will never get to the end. [&#8230;] You could write a unit to verify that the reference [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2025-06-20T20:40:34Z","apple_news_api_id":"2892cee1-4287-416d-976c-343b1bbc1515","apple_news_api_modified_at":"2025-06-26T15:09:44Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/AKJLO4UKHQW2XbDQ7G7wVFQ","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[55,571,71,2200,901],"class_list":["post-48170","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-arc","tag-memory-management","tag-programming","tag-swift-concurrency","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/48170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=48170"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/48170\/revisions"}],"predecessor-version":[{"id":48240,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/48170\/revisions\/48240"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=48170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=48170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=48170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}