{"id":18763,"date":"2017-08-29T13:47:55","date_gmt":"2017-08-29T17:47:55","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=18763"},"modified":"2020-04-21T13:57:39","modified_gmt":"2020-04-21T17:57:39","slug":"swift-4-bridging-peephole-for-as-casts","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2017\/08\/29\/swift-4-bridging-peephole-for-as-casts\/","title":{"rendered":"Swift 4: Bridging Peephole for &ldquo;as&rdquo; Casts"},"content":{"rendered":"<p><a href=\"https:\/\/forums.swift.org\/t\/rfc-bridging-peephole-for-as-casts\/6108\">John McCall<\/a> (via <a href=\"https:\/\/twitter.com\/steipete\/status\/902247491235717121\">Peter Steinberger<\/a>):<\/p>\n<blockquote cite=\"https:\/\/forums.swift.org\/t\/rfc-bridging-peephole-for-as-casts\/6108\">\n<p>Bridging conversions are not always desirable.  First, they do impose some performance overhead which the user may not want.  But they can also change semantics in unwanted ways.  For example, in certain rare situations, the reference identity of an <code>NSString<\/code> return value is important &mdash; maybe it's actually a persistent <code>NSMutableString<\/code> which should be modified in-place, or maybe it's a subclass which carries additional information.  A pair of bridging conversions from <code>NSString<\/code> to <code>String<\/code> and then back to <code>NSString<\/code> is likely to lose this reference identity.  In the current representation, <code>String<\/code> can store an <code>NSString<\/code> reference, and if the <code>String<\/code> is bridged to <code>NSString<\/code> that reference will be used as the result; however, the bridging conversion from <code>NSString<\/code> does not directly store the original <code>NSString<\/code> in the <code>String<\/code>, but instead stores the result of invoking <code>+copy<\/code> on it, in an effort to protect against the original <code>NSString<\/code> being somehow mutable.<\/p>\n<p>Bridging conversions arising from reasons #1 and #2 are avoidable, but bridging conversions arising from reason #3 currently cannot be eliminated without major inconvenience, such as writing a stub in Objective-C.  This is unsatisfactory.  At the same time, it is not valid for Swift to simply eliminate pairs of bridging conversions as a matter of course, precisely because those bridging conversions can be semantically important.  We do not want optimization settings to be able to affect things as important as whether a particular <code>NSString<\/code> is mutable or not.<\/p>\n<\/blockquote>\n<p>He proposes eliminating pairs of bridging conversions <a href=\"https:\/\/forums.swift.org\/t\/rfc-bridging-peephole-for-as-casts\/6108\/3\">under certain circumstances<\/a>:<\/p>\n<blockquote cite=\"https:\/\/forums.swift.org\/t\/rfc-bridging-peephole-for-as-casts\/6108\/3\"><p>This would avoid the bridging conversions through <code>[View]<\/code> on the return value of the getter:<\/p>\n<pre>let subviews = view.subviews as NSArray<\/pre>\n<p>This would not:<\/p>\n<pre>let subviews = view.subviews\nlet nsSubviews = subviews as NSArray<\/pre>\n<p>This would avoid the bridging conversion through <code>[CIFilter]<\/code> on the argument to the setter:<\/p>\n<pre>view.backgroundFilters = nsFilters as [CIFilter]<\/pre>\n<p>This would not:<\/p>\n<pre>let filters = nsFilters as [CIFilter]\nview.backgroundFilters = filters<\/pre>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>John McCall (via Peter Steinberger): Bridging conversions are not always desirable. First, they do impose some performance overhead which the user may not want. But they can also change semantics in unwanted ways. For example, in certain rare situations, the reference identity of an NSString return value is important &mdash; maybe it's actually a persistent [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2020-04-21T17:55:18Z","apple_news_api_id":"d0771acf-87be-4867-aa57-f68ce35d337e","apple_news_api_modified_at":"2020-04-21T17:57:42Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/A0Hcaz4e-SGeqV_aM410zfg","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":[46,71,901],"class_list":["post-18763","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-languagedesign","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18763","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=18763"}],"version-history":[{"count":3,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18763\/revisions"}],"predecessor-version":[{"id":28730,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/18763\/revisions\/28730"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=18763"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=18763"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=18763"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}