{"id":80,"date":"2010-06-22T17:52:30","date_gmt":"2010-06-23T01:52:30","guid":{"rendered":"http:\/\/bynomial.com\/blog\/?p=80"},"modified":"2010-06-22T17:52:30","modified_gmt":"2010-06-23T01:52:30","slug":"clash-happy-method-names","status":"publish","type":"post","link":"http:\/\/bynomial.com\/blog\/?p=80","title":{"rendered":"Clash-happy method names"},"content":{"rendered":"<p>This post lists a few special-case method names that are somewhat likely to be used accidentally by you but can only be used correctly if you understand their built-in functions. \u00c2\u00a0Specifically: class, description, load, and hash.<\/p>\n<h2>Why it&#8217;s tricky, by example<\/h2>\n<p>Here&#8217;s an easy way to mess this up: start with a model object meant to match a table of a database on your server. \u00c2\u00a0Maybe you started by defining your fields. \u00c2\u00a0You&#8217;re making a table to represent player characters, so they have properties like alignment, level, race, or class. \u00c2\u00a0Sounds fine, right? \u00c2\u00a0Next you mirror these types in your iOS code, with just a bunch of instance variables with the same names. \u00c2\u00a0Instance variable names won&#8217;t class with method names, so you&#8217;re still ok. \u00c2\u00a0And then down the road you want to turn these things into properties. \u00c2\u00a0So you mindlessly turn everything into a property and <strong>BAM<\/strong> your code suddenly starts acting extremely weird, and you have no idea why.<\/p>\n<p>It&#8217;s because you implicitly have defined a method called &#8220;class&#8221; when you declared all your instance variables as property, and you copied all those from your server&#8217;s table fields. \u00c2\u00a0Now you have a choice:<\/p>\n<p>1. Make your code uglier by avoiding properties, or<\/p>\n<p>2. Make your code uglier by dropping consistency, and do some special-case handling for the &#8220;class&#8221; field.<\/p>\n<p>Of course, the <em>real<\/em> solution is<\/p>\n<p>3. Don&#8217;t use clash-friendly names <em>anywhere<\/em> in your pipeline, even across platforms.<\/p>\n<p>Hence the usefulness of this post (there are other cases too). \u00c2\u00a0Some people might argue in favor of<\/p>\n<p>4? Change every single instance variable everywhere to start (or end) with an underscore to avoid name clashes,<\/p>\n<p>but I think it is confusing to even allow names that are off-by-an-underscore, and that it is more a work-around than a good general approach. \u00c2\u00a0But that is also a prevalent and valid perspective.<\/p>\n<p>In any case, it&#8217;s good to know about these few special-case methods:<\/p>\n<h2>class<\/h2>\n<p>This method is meant to return the<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">Class<\/div><\/div>\n<p>object for the class of the receiver.  You never need to write it, and overriding it is probably not your best move.  It can be used for things like deciding what methods your object can respond to, and confusion about that can lead to horrible burning crashes with blood, disembodied limbs, and gory stack traces flying willy-nilly about the room.<\/p>\n<h2>description<\/h2>\n<p>Beginners often think (at least I did) that %@, as a string formatter, means &#8220;print out an NSString.&#8221;  But that&#8217;s not true &#8211; it really means, &#8220;print out an object,&#8221; and an object can be <em>anything<\/em>, including an NSString (so if you previously thought it was for NSString&#8217;s, your thought is true &#8211; it&#8217;s just that you can print out so much more than you ever dreamed).  Of course, there is the big question of <em>how do you convert any object to a string?<\/em> And the answer is that every object has a<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">description<\/div><\/div>\n<p>method which is meant to return a string representing that object.  If you override this method, anyone printing your object (which could easily happen indirectly by, say, printing out the contents of an NSArray) will invoke your description call &#8212; if you provide some other type of<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">description<\/div><\/div>\n<p>method, you will end up scratching your head at the weird debug output you get.<\/p>\n<h2>load<\/h2>\n<p>The<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">load<\/div><\/div>\n<p>method is a class method (signature + (void)[<em>MyClass<\/em> load]).  It is designed to give you a chance to run some code at the load-time of a binary, in a way that does not require any specific invocation.  For example, you could build an audio library that has to call some one-time global init function like AudioInit().  Instead of having run-once code in your init function that looks like this:<\/p>\n<pre>if (didGlobalInit == NO) {\r\n  AudioInit();\r\n  didGlobalInit = YES;\r\n}<\/pre>\n<p>You can just do this:<\/p>\n<pre>+ (void)load {\r\n  AudioInit();\r\n}<\/pre>\n<p>So if you were thinking of have static methods called<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">load<\/div><\/div>\n<p>and<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">save<\/div><\/div>\n<p>meant to be called explicitly by your own code, you need to choose new names.<\/p>\n<h2>hash<\/h2>\n<p>The hash method is used by collections like dictionaries and sets to do fast lookups (<a href=\"http:\/\/bynomial.com\/blog\/?p=73\">more info \u00c2\u00a0on that here<\/a>). \u00c2\u00a0If you override it for your own hash purposes, your dictionaries and sets are most likely to (a) simply act like things you added aren&#8217;t there during lookups, or (b) possibly crash.<\/p>\n<h2>Others?<\/h2>\n<p>I&#8217;m probably leaving out a few.  Please let me know if you&#8217;ve collided with other special-case names that you weren&#8217;t expecting &#8211; I&#8217;ll add them to this list.<\/p>\n<h2>References<\/h2>\n<p>Apple&#8217;s docs on:<\/p>\n<ul>\n<li><a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/cocoa\/reference\/foundation\/Protocols\/NSObject_Protocol\/Reference\/NSObject.html#\/\/apple_ref\/occ\/intfm\/NSObject\/class\">class<\/a><\/li>\n<li><a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/cocoa\/reference\/foundation\/Protocols\/NSObject_Protocol\/Reference\/NSObject.html#\/\/apple_ref\/occ\/intfm\/NSObject\/description\">description<\/a><\/li>\n<li><a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/cocoa\/reference\/foundation\/Classes\/NSObject_Class\/Reference\/Reference.html#\/\/apple_ref\/occ\/clm\/NSObject\/load\">load<\/a><\/li>\n<li><a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/cocoa\/reference\/foundation\/Protocols\/NSObject_Protocol\/Reference\/NSObject.html#\/\/apple_ref\/occ\/intfm\/NSObject\/hash\">hash<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This post lists a few special-case method names that are somewhat likely to be used accidentally by you but can only be used correctly if you understand their built-in functions. \u00c2\u00a0Specifically: class, description, load, and hash. Why it&#8217;s tricky, by example Here&#8217;s an easy way to mess this up: start with a model object meant [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false},"categories":[59,11,12,4],"tags":[70,71,73,72],"_links":{"self":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/80"}],"collection":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=80"}],"version-history":[{"count":0,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/80\/revisions"}],"wp:attachment":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}