{"id":46526,"date":"2025-01-24T14:53:07","date_gmt":"2025-01-24T19:53:07","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=46526"},"modified":"2025-01-24T14:53:07","modified_gmt":"2025-01-24T19:53:07","slug":"debug-descriptions-on-the-wrong-thread","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2025\/01\/24\/debug-descriptions-on-the-wrong-thread\/","title":{"rendered":"Debug Descriptions on the Wrong Thread"},"content":{"rendered":"<p><a href=\"https:\/\/douglashill.co\/2025\/description-concurrency\/\">Douglas Hill<\/a> (<a href=\"https:\/\/bsky.app\/profile\/douglashill.co\/post\/3lgdzmlqk4h2s\">Bluesky<\/a>):<\/p>\n<blockquote cite=\"https:\/\/douglashill.co\/2025\/description-concurrency\/\">\n<p>Is there a best practice for implementing <code>description<\/code> and <code>debugDescription<\/code> for main actor classes with Swift strict concurrency?<\/p>\n<\/blockquote>\n<p>Currently, he&rsquo;s checking the current thread and not trying to read the object if it&rsquo;s the wrong one.<\/p>\n<p>I&rsquo;ve run into a similar issue with Core Data. Managed objects are supposed to be confined to a single queue, but it&rsquo;s easy for them to leak, as they get included in the user info dictionaries of notifications and errors. If you try to log an error you&rsquo;ll get undefined behavior or a crash if <code>com.apple.CoreData.ConcurrencyDebug<\/code> is enabled.<\/p>\n<p>Maybe it&rsquo;s OK to override <code>description<\/code> and dispatch it to the correct queue. The object knows its own context, after all, and the context knows the queue. But I&rsquo;ve always had the suspicion that performing within <code>description<\/code> could cause a deadlock or something. So, instead, I sometimes try to catch Core Data errors and generate\/store the description before they cross the thread boundary.<\/p>","protected":false},"excerpt":{"rendered":"<p>Douglas Hill (Bluesky): Is there a best practice for implementing description and debugDescription for main actor classes with Swift strict concurrency? Currently, he&rsquo;s checking the current thread and not trying to read the object if it&rsquo;s the wrong one. I&rsquo;ve run into a similar issue with Core Data. Managed objects are supposed to be confined [&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-01-24T19:53:10Z","apple_news_api_id":"91dfcaa2-e69a-4b4c-9174-31d153b690a6","apple_news_api_modified_at":"2025-01-24T19:53:10Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/Akd_KouaaS0yRdDHRU7aQpg","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":[800,109,31,2586,30,2598,71,2200],"class_list":["post-46526","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-concurrency","tag-coredata","tag-ios","tag-ios-18","tag-mac","tag-macos-15-sequoia","tag-programming","tag-swift-concurrency"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/46526","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=46526"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/46526\/revisions"}],"predecessor-version":[{"id":46527,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/46526\/revisions\/46527"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=46526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=46526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=46526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}