{"id":16090,"date":"2016-10-18T16:26:31","date_gmt":"2016-10-18T20:26:31","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=16090"},"modified":"2020-04-23T15:31:32","modified_gmt":"2020-04-23T19:31:32","slug":"working-without-a-nib","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2016\/10\/18\/working-without-a-nib\/","title":{"rendered":"Working Without a Nib"},"content":{"rendered":"<p><a href=\"http:\/\/lapcatsoftware.com\/articles\/working-without-a-nib-part-8-the-nib-awakens.html\">Jeff Johnson<\/a>:<\/p>\n<blockquote cite=\"http:\/\/lapcatsoftware.com\/articles\/working-without-a-nib-part-8-the-nib-awakens.html\">\n<p>Four score and minus seventy-two years ago, I brought forth on this internet <a href=\"http:\/\/lapcatsoftware.com\/blog\/2008\/10\/20\/working-without-a-nib-part-7-the-empire-strikes-back\/\">a new blog post<\/a>, conceived in levity, and dedicated to the proposition that no nibs are created. Since then, much has changed in the Mac world.<\/p>\n<p>[&#8230;]<\/p>\n<p>The problem is that you need to call <code>[myWindow setReleasedWhenClosed:NO]<\/code>. In pre-ARC code, this would not be surprising to old-school Cocoa coders. However, ARC does not even allow you to use the <code>-release<\/code> and <code>-autorelease<\/code> methods, so you might think that <code>-setReleasedWhenClosed:<\/code> would not be allowed either, or would at least be ignored. And you would be very wrong.<\/p>\n<\/blockquote>\n<p>My goal is to make all my projects nibless. Nib and xib files have caused me no end of problems. Even files that haven&rsquo;t been edited in years spontaneously stop working when Xcode is updated and its xib compiler changes. (Most of the problems manifested on previous OS versions, where it was harder to detect them and to test fixes.) And that&rsquo;s to say nothing of the advantages that doing interfaces with code offers. I&rsquo;m convinced that with current technology (e.g. Auto Layout, Swift), using Interface Builder is a poor time investment for non-temporary projects. As Johnson <a href=\"https:\/\/twitter.com\/lapcatsoftware\/status\/788084725021872128\">writes<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/lapcatsoftware\/status\/788084725021872128\"><p>Initial nib UI implementation is faster, but it&rsquo;ll haunt you forever.<\/p><\/blockquote>\n<p>I&rsquo;m leaning the same way about Core Data models, except that there seem to be places where the frameworks really want to have a model file saved to disk.<\/p>\n<p>Update (2016-10-19): <a href=\"https:\/\/twitter.com\/wooliegeek\/status\/788589122436947970\">Steven Woolgar<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/wooliegeek\/status\/788589122436947970\"><p>Especially with ibtool failing randomly all the damned time.<\/p><\/blockquote>\n<p><a href=\"https:\/\/twitter.com\/marcoarment\/status\/788548752885809153\">Marco Arment<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/marcoarment\/status\/788548752885809153\"><p>I take back everything nice I said about Interface Builder a few weeks ago on Under The Radar.<\/p><\/blockquote>\n<p><a href=\"https:\/\/twitter.com\/vadimshpakovski\/status\/788777094289514496\">Vadim<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/vadimshpakovski\/status\/788777094289514496\"><p>After introducing NSStackView there is no more excuse to build any UIs in IB.<\/p><\/blockquote>\n<p>Previously: <a href=\"http:\/\/mjtsai.com\/blog\/2013\/03\/14\/simmons-interface-builder\/\">How Much, or How Little, I Use Interface Builder These Days<\/a>, <a href=\"http:\/\/mjtsai.com\/blog\/2014\/05\/06\/stopped-using-nibs-thanks-to-auto-layout\/\">Stopped Using NIBs Thanks to Auto Layout<\/a>, <a href=\"http:\/\/mjtsai.com\/blog\/2015\/11\/12\/decoding-old-nibs\/\">Decoding Old Nibs: a Sad Tale of Vendor Lock-in and Abandonment<\/a>.<\/p>\n\n<p>Update (2016-10-20): <a href=\"https:\/\/www.raizlabs.com\/dev\/2016\/08\/ib-free-living-without-interface-builder\/\">John Stricker<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.raizlabs.com\/dev\/2016\/08\/ib-free-living-without-interface-builder\/\">\n<p>If you were to restrict yourself to using interface builder for this layout, there are many limitations:<\/p>\n<ol>\n<li>you couldn&rsquo;t as easily preserve two different styles of the view<\/li>\n<li>you wouldn&rsquo;t be able to use loops, constants and enums to lay out the view<\/li>\n<li>you wouldn&rsquo;t be able to adjust the content, size and layouts of the buttons all at once.<\/li>\n<\/ol>\n<\/blockquote>\n\n<p>Update (2016-10-21): <a href=\"https:\/\/twitter.com\/peternlewis\/status\/789290897129164800\">Peter N Lewis<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/peternlewis\/status\/789290897129164800\"><p>I use xib&rsquo;s for everything in Keyboard Maestro. And have special Lint code to detect inconsistencies. Coming to the conclusion I'm an idiot.<\/p><\/blockquote>\n\n<p>Update (2017-06-29): <a href=\"http:\/\/lapcatsoftware.com\/articles\/working-without-a-nib-part-10.html\">Jeff Johnson<\/a>:<\/p>\n<blockquote cite=\"http:\/\/lapcatsoftware.com\/articles\/working-without-a-nib-part-10.html\"><p>Many years ago I posted a sample nibless application on my old blog, but since then &#8230; much has changed. Given the renewed interest, I've decided to post a brand new sample application.<\/p><\/blockquote>\n\n<p>Update (2017-07-01): See also: <a href=\"https:\/\/devchat.tv\/iphreaks\/underpass-with-jeff-johnson\">iPhreaks Show<\/a>.<\/p>\n\n<p id=\"working-without-a-nib-update-2019-03-07\">Update (2019-03-07): <a href=\"https:\/\/gist.github.com\/0xced\/6ded369c976d858860a6f8a4517a0654\">C&eacute;dric Luthi<\/a> links to all 11 parts of Johnson&rsquo;s series (<a href=\"https:\/\/twitter.com\/0xced\/status\/1103733203569922048\">tweet<\/a>).<\/p>\n\n<p id=\"working-without-a-nib-update-2020-04-23\">Update (2020-04-23): <a href=\"https:\/\/lapcatsoftware.com\/articles\/working-without-a-nib-part-12.html\">Jeff Johnson<\/a>:<\/p>\n<blockquote cite=\"https:\/\/lapcatsoftware.com\/articles\/working-without-a-nib-part-12.html\"><p>So what happens is that NSApplication keeps a strong reference to all open windows in its ivar <code>_openWindows<\/code> if the app uses the 10.13 SDK or later, otherwise it doesn&rsquo;t keep a strong reference, and you&rsquo;re on your own. Note that the 10.13+ behavior can be overridden by setting the NSUserDefault <code>NSApplicationStronglyReferencesOpenWindows<\/code> to false, which gives you the 10.12- behavior again.<\/p><p>[&#8230;]<\/p><p>The good news, however, is that if your app does have a deployment target of 10.13 or higher, then the memory management of <code>NSWindow<\/code> becomes relatively simple. It&rsquo;s almost &ldquo;magical&rdquo; again, and we didn&rsquo;t need <code>NSWindowController<\/code>.<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Jeff Johnson: Four score and minus seventy-two years ago, I brought forth on this internet a new blog post, conceived in levity, and dedicated to the proposition that no nibs are created. Since then, much has changed in the Mac world. [&#8230;] The problem is that you need to call [myWindow setReleasedWhenClosed:NO]. In pre-ARC code, [&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-03-07T20:25:48Z","apple_news_api_id":"9da20411-5fb2-4d38-bbd0-2975fe59bbe9","apple_news_api_modified_at":"2020-04-23T19:31:36Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/AnaIEEV-yTTi70Cl1_lm76Q","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":[200,55,69,109,649,370,30,1381,571,54,71],"class_list":["post-16090","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-autolayout","tag-arc","tag-cocoa","tag-coredata","tag-esoteric-preferences","tag-interfacebuilder","tag-mac","tag-macos-10-12","tag-memory-management","tag-objective-c","tag-programming"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/16090","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=16090"}],"version-history":[{"count":9,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/16090\/revisions"}],"predecessor-version":[{"id":28788,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/16090\/revisions\/28788"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=16090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=16090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=16090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}