{"id":27298,"date":"2019-11-19T15:53:42","date_gmt":"2019-11-19T20:53:42","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=27298"},"modified":"2019-12-17T16:31:10","modified_gmt":"2019-12-17T21:31:10","slug":"direct-objective-c-properties","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2019\/11\/19\/direct-objective-c-properties\/","title":{"rendered":"Direct Objective-C Properties"},"content":{"rendered":"<p>In a <a href=\"https:\/\/github.com\/llvm\/llvm-project\/commit\/d4e1ba3fa9dfec2613bdcc7db0b58dea490c56b1\">future compiler version<\/a>:<\/p>\n<blockquote cite=\"https:\/\/github.com\/llvm\/llvm-project\/commit\/d4e1ba3fa9dfec2613bdcc7db0b58dea490c56b1\"><p>A <code>direct<\/code> property specifier is added (<code>@Property(direct) type name<\/code>)<\/p>\n<p>These attributes \/ specifiers cause the method to have no associated\nObjective-C metadata (for the property or the method itself), and the\ncalling convention to be a direct C function call.<\/p>\n<p>The symbol for the method has enforced hidden visibility and such direct\ncalls are hence unreachable cross image. An explicit C function must be\nmade if so desired to wrap them.<\/p><\/blockquote>\n<p>Via <a href=\"https:\/\/twitter.com\/NSExceptional\/status\/1196640949289586688\">Tanner Bennett<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/NSExceptional\/status\/1196640949289586688\"><p>This feature tries it&rsquo;s hardest to break everything that makes Objc great. KVC, KVO, swizzling, etc., even OOP because this is effectively <code>final<\/code> for objc. In case anyone was wondering why I&rsquo;m disappointed in this addition.<\/p>\n<p>I can only hope codebases adopt it sparingly.<\/p><\/blockquote>\n<p><a href=\"https:\/\/twitter.com\/gparker\/status\/1196778399210958848\">Greg Parker<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/gparker\/status\/1196778399210958848\">\n<p>Counterargument: the alternative to get this level of performance is to rewrite your method as a C function. That experience is awful in practice. It&rsquo;s important to be able to tune dynamism vs performance without busy-work syntax changes.<\/p>\n<\/blockquote>\n<p>It&rsquo;s a great feature to have for this reason. But I hope it&rsquo;s not overused.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2014\/08\/18\/its-a-coup\/\">&ldquo;It&rsquo;s a Coup&rdquo;<\/a><\/li>\n<\/ul>\n\n<p id=\"direct-objective-c-properties-update-2019-11-20\">Update (2019-11-20): <a href=\"https:\/\/twitter.com\/jmfd\/status\/1196898740876922880\">Jonathan Deutsch<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/jmfd\/status\/1196898740876922880\"><p>Counter-counter argument: this is needed rarely, and much more rarely than many will think it is needed.<\/p><p>In my experience, most developers jump at the opportunity for &ldquo;performance&rdquo; even when premature, not measured, and probably not going to be effective.<\/p><p>Part of Objective-C&rsquo;s beauty was that it was simple. One used to be able to easily learn the language, read others&rsquo; code, and thus debug others&rsquo; code.<\/p><p>There&rsquo;s no feature in a language of higher priority than this&#8230; definitely not performance.<\/p><\/blockquote>\n<p>Although one could argue that this feature makes the optimized code <em>more<\/em> readable.<\/p>\n<p>See also: <a href=\"https:\/\/twitter.com\/steipete\/status\/1196771019324829697\">this thread<\/a>.<\/p>\n\n<p id=\"direct-objective-c-properties-update-2019-11-27\">Update (2019-11-27): <a href=\"https:\/\/twitter.com\/pedantcoder\/status\/1197269246289444864\">Pierre Habouzit<\/a> (<a href=\"https:\/\/threadreaderapp.com\/thread\/1197269246289444864.html\">thread<\/a>):<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/pedantcoder\/status\/1197269246289444864\"><p>The Obj-C dynamic dispatch comes with many costs, this is common &ldquo;knowledge&rdquo;. However the details of it are rarely known.<\/p><p>Beside the obvious cost of the h-lookup, it comes with 4 other kinds of costs:<\/p><p>- codegen size<br \/>\n- optimization barrier<br \/>\n- static metadate<br \/>\n- runtime metadata<\/p><p>[&#8230;]<\/p><p>When used on a typical Obj-C framework, it is easy to reduce your binary size by 5% or more. Using LTO will easily make this win even larger. It means in turn that the working-set of the processes is smaller, which gives you more space for things that are actually useful.<\/p><p>As such, you now start to see that despite the obvious initial reaction which is &ldquo;holy s**t this is great for hot code&rdquo;, the target audience is even more the long tail of rarely used monomorphic calls that are killing your binary size for very little added value.<\/p><\/blockquote>\n\n<p id=\"direct-objective-c-properties-update-2019-12-17\">Update (2019-12-17): <a href=\"https:\/\/twitter.com\/stroughtonsmith\/status\/1199809415433637888\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/stroughtonsmith\/status\/1199809415433637888\">\n<p>As far as things that make my life harder, inlining ObjC methods isn&rsquo;t one of them. Getting human-readable disassembly out of Swift code is a nightmare, on the other hand. I&rsquo;m far more concerned about Swift adoption increasing than improvements to ObjC<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/twitter.com\/lgerbarg\/status\/1201632083929485314\">Louis Gerbarg<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/lgerbarg\/status\/1201632083929485314\">\n<p>The best part about that thread is that I am about 90% the StepStone ObjC compiler actually had a keyword with pretty much the same semantics as objc_direct. Unfortunately I can&rsquo;t find any documentation for it.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/twitter.com\/pedantcoder\/status\/1201632421893959680\">Pierre Habouzit<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/pedantcoder\/status\/1201632421893959680\">\n<p>Not exactly. But close. The radar has it. It used to be <code>- ([inline] __direct__ type)mySelector...;<\/code><\/p>\n<\/blockquote>\n\n<p>See also: <a href=\"https:\/\/nshipster.com\/direct\/\">Mattt Thompson<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>In a future compiler version: A direct property specifier is added (@Property(direct) type name) These attributes \/ specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and [&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":"2019-11-19T20:53:47Z","apple_news_api_id":"64f72353-5cd2-4b56-a78f-0fd9ba426920","apple_news_api_modified_at":"2019-12-17T21:31:14Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAw==","apple_news_api_share_url":"https:\/\/apple.news\/AZPcjU1zSS1anjw_ZukJpIA","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":[31,1837,46,30,32,1891,966,54,760,138,71],"class_list":["post-27298","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-ios","tag-ios-14","tag-languagedesign","tag-mac","tag-macapp","tag-macos-11-0","tag-message-passing","tag-objective-c","tag-objective-c-runtime","tag-optimization","tag-programming"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/27298","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=27298"}],"version-history":[{"count":5,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/27298\/revisions"}],"predecessor-version":[{"id":27596,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/27298\/revisions\/27596"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=27298"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=27298"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=27298"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}