{"id":9336,"date":"2014-08-18T14:07:17","date_gmt":"2014-08-18T18:07:17","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=9336"},"modified":"2015-12-17T13:06:50","modified_gmt":"2015-12-17T18:06:50","slug":"its-a-coup","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2014\/08\/18\/its-a-coup\/","title":{"rendered":"&ldquo;It&rsquo;s a Coup&rdquo;"},"content":{"rendered":"<p>I highly recommend the Edge Cases episode <a href=\"http:\/\/edgecasesshow.com\/099-swift-is-a-really-good-thing-and-a-step-back.html\">Swift Is a Really Good Thing and a Step Back<\/a>. There&rsquo;s much to like about Swift, but much has been lost as well: <a href=\"http:\/\/mjtsai.com\/blog\/2014\/06\/13\/instantiating-classes-by-name-in-swift\/\">instantiating classes by name<\/a>, the ability to write your own Core Data&#8211;like framework, <a href=\"http:\/\/mjtsai.com\/blog\/2014\/06\/27\/the-case-for-message-passing-in-swift\/\">message passing<\/a> (contra vtable dispatch), swizzling to <a href=\"http:\/\/blog.jaredsinclair.com\/post\/93992930295\/for-subclass-eyes-only-swift-uigesturerecognizer-and\">work around bugs<\/a> and to add features, proxies\/bridges, and more.<\/p>\r\n<p>The quote in this post&rsquo;s title, from Andrew Pontious, refers to the general lack of outrage over the loss of dynamism. In broad strokes, the C++ people have asserted their vision that the future will be static, and the reaction from the Objective-C crowd has been apathy. Apple hasn&rsquo;t even really tried to make a case for why this U-turn is a good idea, and yet the majority seems to have rolled over and accepted it, anyway.<\/p>\r\n<p>Since the episode was released, there&rsquo;s been some good news: Wolf Rentzsch is <a href=\"http:\/\/edgecasesshow.com\/100-apps-for-iwatch-and-apple-tv.html\">not leaving Edge Cases<\/a>, as was <a href=\"https:\/\/twitter.com\/iTod\/status\/496682850260111361\">implied<\/a>. More mixed is the news of the significant changes that Apple has made to Swift in beta 5.<\/p>\r\n<p>The latest version of <a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/Swift\/Conceptual\/Swift_Programming_Language\/Declarations.html#\/\/apple_ref\/doc\/uid\/TP40014097-CH34-XID_525\">The Swift Programming Language<\/a> discusses the new <code>dynamic<\/code> modifier:<\/p>\r\n<blockquote cite=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/Swift\/Conceptual\/Swift_Programming_Language\/Declarations.html#\/\/apple_ref\/doc\/uid\/TP40014097-CH34-XID_525\"><p>Apply this modifier to any member of a class that can be represented by Objective-C. When you mark a member declaration with the <code>dynamic<\/code> modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.\r\n<\/p><p>Because declarations marked with the <code>dynamic<\/code> modifier are dispatched using the Objective-C runtime, they&rsquo;re implicitly marked with the <code>objc<\/code> attribute.<\/p><\/blockquote>\r\n<p>Previously, there was only the <code>@objc<\/code> attribute, and this made it seem like message passing was deprecated. The only way to get it was via the Objective-C compatibility layer, and the <code>@<\/code> sign emphasized that it was not part of the language proper.<\/p>\r\n<p>One way to interpret the addition of the <code>dynamic<\/code> modifier, which lacks a <code>@<\/code>, is that Apple plans for message passing to be at least an optional part of Swift going forward. It&rsquo;s currently <em>implemented<\/em> using the Objective-C runtime, but it&rsquo;s no longer tied to <code>@objc<\/code>. In a future release, there could be pure Swift classes that use message passing.<\/p>\r\n<p>However, the other half of this change is that <em>methods in Objective-C classes are no longer dynamic by default.<\/em> The <code>dynamic<\/code> modifier doesn&rsquo;t actually make things more dynamic; rather, Apple has made everything more static but allowed you to opt out by annotating individual methods. To define an Objective-C method, you used to type just <code>-<\/code>. Now you must type <code>func dynamic<\/code>. This reminds me of how you have to type <code>nonatomic<\/code> on most Objective-C properties because the <a href=\"https:\/\/developer.apple.com\/library\/mac\/documentation\/Cocoa\/Conceptual\/ProgrammingWithObjectiveC\/EncapsulatingData\/EncapsulatingData.html#\/\/apple_ref\/doc\/uid\/TP40011210-CH5-SW37\">default<\/a> is usually not what you want.<\/p>\r\n<p>The latest version of <a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/Swift\/Conceptual\/BuildingCocoaApps\/InteractingWithObjective-CAPIs.html#\/\/apple_ref\/doc\/uid\/TP40014216-CH4-XID_38\">Using Swift with Cocoa and Objective-C<\/a> says:<\/p>\r\n<blockquote cite=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/Swift\/Conceptual\/BuildingCocoaApps\/InteractingWithObjective-CAPIs.html#\/\/apple_ref\/doc\/uid\/TP40014216-CH4-XID_38\"><p>While the <code>@objc<\/code> attribute exposes your Swift API to the Objective-C runtime, it does not guarantee dynamic dispatch of a property, method, subscript, or initializer. The Swift compiler may still devirtualize or inline member access to optimize the performance of your code, bypassing the Objective-C runtime. When you mark a member declaration with the <code>dynamic<\/code> modifier, access to that member is always dynamically dispatched. Because declarations marked with the <code>dynamic<\/code> modifier are dispatched using the Objective-C runtime, they&rsquo;re implicitly marked with the <code>@objc<\/code> attribute.\r\n<\/p><p>Requiring dynamic dispatch is rarely necessary. However, you must use the <code>dynamic<\/code> modifier when you know that the implementation of an API is replaced at runtime. For example, you can use the <code>method_exchangeImplementations<\/code> function in the Objective-C runtime to swap out the implementation of a method while an app is running. If the Swift compiler inlined the implementation of the method or devirtualized access to it, the new implementation would not be used.<\/p><\/blockquote>\r\n<p>The good news is that Apple has found a way to speed up Objective-C classes in Swift. Presumably, this only applies to methods that are compiled into the same binary as their callers. My guess is that calls into the Cocoa frameworks cannot be optimized in this way.<\/p>\r\n<p>The bad news is that, by default, your objects will no longer work with KVO or swizzling. If the designer of a class doesn&rsquo;t anticipate a reason for a particular method or property to be dynamic, that lack of foresight gets baked in at compile time.<\/p>\r\n<p>In my view, this is a mistake. It makes sense for dynamism to be the default because the costs are low. Objective-C message dispatch is very fast&mdash;famously running on 68030 hardware and of course the original iPhone. And, secondly, the Pareto principle applies: when message passing <em>is<\/em> a bottleneck, most of the gains can be obtained by making just a few hot spots more static (e.g. using <code>IMP<\/code>-caching).<\/p>\r\n<p>The costs for not using message passing, on the other hand, can be high because they make the code more rigid\/brittle. You cannot retroactively make compiled code more dynamic\/flexible. And yet, since <code>dynamic<\/code> is not the default, the odds are that a lot more methods will be static than need to be. Most of the time, <code>objc_msgSend<\/code> is not why your code is slow, yet Swift acts like it needs to protect you from this.<\/p>\r\n<p>The common case is that message sending is fast enough and that programmers are not smart enough to predict all the ways their code will be used in the future. So Apple should optimize for that and make <code>dynamic<\/code> the default.<\/p>","protected":false},"excerpt":{"rendered":"<p>I highly recommend the Edge Cases episode Swift Is a Really Good Thing and a Step Back. There&rsquo;s much to like about Swift, but much has been lost as well: instantiating classes by name, the ability to write your own Core Data&#8211;like framework, message passing (contra vtable dispatch), swizzling to work around bugs and to [&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":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","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,966,54,760,138,901],"class_list":["post-9336","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-languagedesign","tag-message-passing","tag-objective-c","tag-objective-c-runtime","tag-optimization","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/9336","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=9336"}],"version-history":[{"count":6,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/9336\/revisions"}],"predecessor-version":[{"id":13146,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/9336\/revisions\/13146"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=9336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=9336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=9336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}