{"id":286,"date":"2009-03-31T13:51:51","date_gmt":"2009-03-31T18:51:51","guid":{"rendered":"http:\/\/vgable.com\/blog\/2009\/03\/31\/how-to-write-cocoa-object-getters\/"},"modified":"2009-04-03T12:58:55","modified_gmt":"2009-04-03T17:58:55","slug":"how-to-write-cocoa-object-getters","status":"publish","type":"post","link":"https:\/\/vgable.com\/blog\/2009\/03\/31\/how-to-write-cocoa-object-getters\/","title":{"rendered":"How To Write Cocoa Object Getters"},"content":{"rendered":"<p>Setters are more straightforward than <a href=\"http:\/\/vgable.com\/blog\/2009\/03\/29\/how-to-write-cocoa-object-setters\/\">getters<\/a>, because you don&#8217;t <em>need<\/em> to worry about memory management. <\/p>\n<p>The best practice is to let the compiler write getters for you, by using <a href=\"http:\/\/developer.apple.com\/documentation\/Cocoa\/Conceptual\/ObjectiveC\/Articles\/ocProperties.html\">Declared Properties<\/a>.<\/p>\n<p>But when I have to implement a getter manually, I prefer the (to my knowledge) safest pattern,<\/p>\n<pre>- (TypeOfX*) x;\n{\n&nbsp;&nbsp;return [[x retain] autorelease];\n}<\/pre>\n<p>Note that by convention in Objective-C, a getter for the variable <code>jabberwocky<\/code> is simply called <code>jabberwocky<\/code>, <em>not<\/em> <code>getJabberwocky<\/code>.<\/p>\n<h3>Why <code>retain<\/code> Then <code>autorelease<\/code><\/h3>\n<p>Basically <code>return [[x retain] autorelease];<\/code> <em>guarantees<\/em> that what the getter returns will be valid for as long as any local objects in the code that called the the getter.<\/p>\n<p>Consider,<\/p>\n<pre>NSString* oldName = [person name];\n[person setName:@\"Alice\"];\nNSLog(@\"%@ has changed their name to Alice\", oldName);<\/pre>\n<p>If <code>-setName:<\/code> immediately <code>release<\/code>es the value that <code>-name<\/code> returned, <code>oldName<\/code> will be invalid when it&#8217;s used in <code>NSLog<\/code>.  But if the implementation of <code>[x name]<\/code> used <code>retain\/autorelease<\/code>, then <code>oldName<\/code> would still be valid, because it would not be destroyed until the autorelease pool around the <code>NSLog<\/code> was drained.<\/p>\n<p>Also, autorelease pools are <em>per thread<\/em>; different threads have different autorelease pools that are drained at different times. <code>retain\/autorelease<\/code> makes sure the object is on the calling thread&#8217;s pool.<\/p>\n<p>If this cursory explanation isn&#8217;t enough, read <a href=\"http:\/\/www.sethwillits.com\/blog\/?p=24\">Seth Willitis&#8217; detailed explanation of <code>retain\/autorelease<\/code><\/a>. I&#8217;m not going to explain it further here, because he&#8217;s done such a through job of it.<\/p>\n<h3>Ugly<\/h3>\n<p><code>return [[x retain] autorelease];<\/code> is more complicated, and harder to understand then a simple <code>return x;<\/code>.  But sometimes that ugliness is necessary, and the best place to hide it is in a one-line getter method. It&#8217;s self documenting. And once you understand Cocoa memory management, it&#8217;s entirely clear what the method does. For me, <strong>the tiny readability cost is worth the safety guarantee<\/strong>.<\/p>\n<h3>Big<\/h3>\n<p><code>return [[x retain] autorelease];<\/code> increases peak memory pressure, because it can defer <code>dealloc<\/code>-ing unused objects  until a few autorelease pools are drained. Honestly I&#8217;ve never measured memory usage, and found this to be a significant problem.  It certainly could be, especially if the thing being returned is a large picture or chunk of data. But in my experience, it&#8217;s nothing to worry about for getters that return typical objects, unless there are measurements saying otherwise.<\/p>\n<h3>Slow<\/h3>\n<p><code>return [[x retain] autorelease];<\/code> is obviously slower then just <code>return x;<\/code>. But I doubt that optimizing an O(1) getter is going to make a significant difference to your application&#8217;s performance &#8212; especially compared to other things you could spend that time optimizing.  So until I have data telling me otherwise, I don&#8217;t worry about adding an the extra method calls.<\/p>\n<h3>This is a Good Rule to Break<\/h3>\n<p>As I mentioned before, getters don&#8217;t <em>need<\/em> to worry about memory management. It could be argued that <strong>the <code>return [[x retain] autorelease];<\/code> pattern is a <em>premature optimization<\/em> of <em>theoretical<\/em> safety at the expense of <em>concrete<\/em> performance<\/strong>.<\/p>\n<p>Good programmers try to avoid premature optimization; so perhaps I&#8217;m wrong to follow this &#8220;safer&#8221; pattern. But until I have data showing otherwise, I like to do the safest thing.<\/p>\n<p><strong>How do you write getters, and <em>why<\/em>?<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Setters are more straightforward than getters, because you don&#8217;t need to worry about memory management. The best practice is to let the compiler write getters for you, by using Declared Properties. But when I have to implement a getter manually, I prefer the (to my knowledge) safest pattern, &#8211; (TypeOfX*) x; { &nbsp;&nbsp;return [[x retain] [&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,203,3,5,4,13],"tags":[376,241,616,279,224,174,375],"class_list":["post-286","post","type-post","status-publish","format-standard","hentry","category-cocoa","category-iphone","category-macosx","category-objective-c","category-programming","category-sample-code","tag-autorelease","tag-best-practices","tag-iphone","tag-mac-os-x","tag-memory-management","tag-nsobject","tag-retain"],"_links":{"self":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/286","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=286"}],"version-history":[{"count":0,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/286\/revisions"}],"wp:attachment":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/media?parent=286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/categories?post=286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/tags?post=286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}