{"id":172,"date":"2008-12-04T02:28:20","date_gmt":"2008-12-04T07:28:20","guid":{"rendered":"http:\/\/vgable.com\/blog\/2008\/12\/04\/cocoa-coding-style-minutia-all-forward-declarations-on-one-line-is-the-one-true-way\/"},"modified":"2010-03-27T17:22:37","modified_gmt":"2010-03-27T22:22:37","slug":"cocoa-coding-style-minutia-all-forward-declarations-on-one-line-is-the-one-true-way","status":"publish","type":"post","link":"https:\/\/vgable.com\/blog\/2008\/12\/04\/cocoa-coding-style-minutia-all-forward-declarations-on-one-line-is-the-one-true-way\/","title":{"rendered":"Cocoa Coding Style Minutia: All Forward Declarations on One Line is the One True Way"},"content":{"rendered":"<p>This is a very petty point, but I believe there&#8217;s a right answer, and since it&#8217;s come up before I&#8217;m going to take the time to justify the best choice.<\/p>\n<h3>Forward Declare Classes on One Line, Not Many Lines<\/h3>\n<p><strong>Right:<\/strong><br \/>\n<code>@class Foo, Bar, Baz...;<br \/><\/code><\/p>\n<p>This is the style that Apple&#8217;s headers generally follow, look at <code><a href=\"file:\/\/localhost\/System\/Library\/Frameworks\/AppKit.framework\/Versions\/C\/Headers\/NSDocument.h\">NSDocument.h<\/a><\/code> for example.<\/p>\n<p><strong>Wrong:<\/strong><br \/>\n<code>@class Foo;<br \/>\n@class Bar;<br \/>\n@class Baz;<br \/>\n...<br \/><\/code><\/p>\n<p>Programming languages are to be read by people first, and interpreted by computers second.  I really do hope anyone in software engineering can take that as an axiom!  <\/p>\n<p>Therefore, always favor brevity above all else with statements that are <em>only<\/em> for the compiler.  They are by far the least important part of the code base.  Keeping them terse minimizes distractions from code that can and should be read.<\/p>\n<p>Naturally, it&#8217;s very hard to find a statement that&#8217;s <em>only<\/em> for the compiler.  I can only think of one such statement in Objective-C, forward declarations of an object with <code>@class<\/code>.<\/p>\n<h3>What Does <code>@class<\/code> Do?<\/h3>\n<p><code>@class Foo;<\/code> tells the compiler that <code>Foo<\/code> is an Objective-C class, so that it knows how much space to reserve in memory for things of type <code>Foo<\/code>.  It does not tell the compiler what methods and ivars a <code>Foo<\/code> has, to do that you need to <code>#import \"Foo.h\"<\/code> (or have an <code>@interface Foo...<\/code> in your .m file.)<\/p>\n<table border=\"1\">\n<tr>\n<th><code>@class Foo;<\/code><\/th>\n<th><code>#import \"Foo.h\"<\/code><\/th>\n<\/tr>\n<tr>\n<td><code>Foo<\/code> is a black box.  You can only use it as an argument.<\/td>\n<td>You can also send messages to <code>Foo<\/code>.<\/td>\n<\/tr>\n<\/table>\n<h3>What is <code>@class<\/code> Good For?<\/h3>\n<p>Since <code>#import \"Foo.h\"<\/code> does everything <code>@class Foo;<\/code> does <em>and more<\/em>, why would you ever use <code>@class<\/code>?  The short answer is <strong>less time wasted compiling<\/strong>.<\/p>\n<p>Lets say you have a <code>Controller<\/code> class, and it has an ivar that&#8217;s a <code>Foo<\/code>.  To get it to compile, you put <code>#import \"Foo.h\"<\/code> inside <code>Controller.h<\/code>.  So far so good.  The problem comes when <code>Foo.h<\/code> is changed.  Now any file that has <code>#import \"Foo.h\"<\/code> in it must be recompiled.  So <code>Controller.h<\/code> has to be recompiled.  So any file that has <code>#import \"Controller.h\"<\/code> in it must <em>also<\/em> be recompiled, and so on.  Many objects that don&#8217;t use <code>Foo<\/code> objects, but do talk to the <code>Controller<\/code> (or to something that talks to something that talks to the <code>Controller<\/code>!) have to be rebuilt as well.  It&#8217;s likely that the entire project would end up being rebuilt.  With even a moderately sized project, that means a <em>lot<\/em> of needless compile time!<\/p>\n<p>One solution is to put a forward-declaration, <code>@class Foo;<\/code>, in <code>Controller.h<\/code>, and <code>#import \"Foo.h\"<\/code> in <code>Controller.m<\/code>, and the few files that actually do something to <code>Foo<\/code> objects. <code>@class Foo;<\/code> gives the compiler just enough information to build an object with a <code>Foo*<\/code> ivar, because it knows how much space that ivar will need in memory.  And since only objects that need to talk to <code>Foo<\/code> objects directly have any dependency on <code>Foo.h<\/code>, changes to <code>Foo<\/code> can be tested quickly.  The first time I tried this solution in one of my projects, compile times dropped from minutes to seconds.<\/p>\n<h3>Readers Need Less <code>@class<\/code><\/h3>\n<p>Forward declarations add value to the development process, as does anything that saves programmers time.  But <code>@class<\/code> tells a human reader <em>nothing<\/em>.  Which is why I say you should use them in your code, but minimize the space they take up, by putting them all on one line.<\/p>\n<p><code>@class Foo;<\/code> tells a reader that &#8220;<code>Foo<\/code> is  black-box that is a class.&#8221;  That adds no useful information.<\/p>\n<p>If the reader does not care about what a <code>Foo<\/code> is (they are treating it as a black box), then knowing that <code>Foo<\/code> is a class is useless information.  <code>Foo<\/code> could be a <code>struct<\/code>, or a bit-field, or a function pointer, or anything else and they still would not need to know to understand the code.<\/p>\n<p>Conversely, if they need to know what a <code>Foo<\/code> is to understand the code, then they need to know more then &#8220;it is a class&#8221;.  They need to see <code>Foo.h<\/code> or documentation &#8212; <code>@class<\/code> just isn&#8217;t enough.<\/p>\n<h3>Exceptions<\/h3>\n<p>I want to again emphasize that this isn&#8217;t a big deal.  I <a href=\"http:\/\/www.codinghorror.com\/blog\/archives\/001124.html\">strongly feel<\/a> that putting all forward declarations on one line is the right answer, but doing it wrong won&#8217;t perceptibly matter in the end.<\/p>\n<p>So I don&#8217;t think there&#8217;s any reason to address exceptions to the rule.  <strong>Do what you gotta do.<\/strong><\/p>\n<h3>Best Practices<\/h3>\n<p>Use <code>@class<\/code> to speed up compile-times as much as you can, but use the keyword <code>@class<\/code> as little as possible, since it is for the compiler, not the person reading the code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a very petty point, but I believe there&#8217;s a right answer, and since it&#8217;s come up before I&#8217;m going to take the time to justify the best choice. Forward Declare Classes on One Line, Not Many Lines Right: @class Foo, Bar, Baz&#8230;; This is the style that Apple&#8217;s headers generally follow, look at [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5,4,8],"tags":[240,241,243,158,242,169],"class_list":["post-172","post","type-post","status-publish","format-standard","hentry","category-cocoa","category-objective-c","category-programming","category-usability","tag-class","tag-best-practices","tag-compilers","tag-optimization","tag-programming-style","tag-software-development"],"_links":{"self":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/comments?post=172"}],"version-history":[{"count":2,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/172\/revisions"}],"predecessor-version":[{"id":590,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/172\/revisions\/590"}],"wp:attachment":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/media?parent=172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/categories?post=172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/tags?post=172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}