{"id":285,"date":"2009-03-29T14:53:40","date_gmt":"2009-03-29T19:53:40","guid":{"rendered":"http:\/\/vgable.com\/blog\/2009\/03\/29\/how-to-write-cocoa-object-setters\/"},"modified":"2009-03-31T13:05:08","modified_gmt":"2009-03-31T18:05:08","slug":"how-to-write-cocoa-object-setters","status":"publish","type":"post","link":"https:\/\/vgable.com\/blog\/2009\/03\/29\/how-to-write-cocoa-object-setters\/","title":{"rendered":"How To Write Cocoa Object Setters"},"content":{"rendered":"<p>There are several ways to write setters for Objective-C\/Cocoa objects that work. But here are the practices I follow; to the best of my knowledge they produce the safest code.<\/p>\n<h3>Principle 0: Don&#8217;t Write a Setter<\/h3>\n<p>When possible, it&#8217;s best to write <a href=\"http:\/\/en.wikipedia.org\/wiki\/Immutable_object\">immutable objects<\/a>.  Generally they are safer, and easier to optimize, especially when it comes to concurrency.<\/p>\n<p>By definition immutable objects have no setters, so <strong>always ask yourself if you <em>really<\/em> need a setter<\/strong>,  before you write one, and whenever revisiting code.<\/p>\n<p>I&#8217;ve removed many of my setters by making the thing they set an argument to the class&#8217;s <code>-initWith:<\/code> constructor.  For example,<\/p>\n<pre>CustomWidget *widget = [[CustomWidget alloc] init];\n[widget setController:self];<\/pre>\n<p>becomes,<\/p>\n<pre>CustomWidget *widget = [[CustomWidget alloc] initWithController:self];<\/pre>\n<p>This is less code, and now, <code>widget<\/code> is never in a partially-ready state with no controller.<\/p>\n<p>It&#8217;s not always practical to do without setters. If an object looks like it needs a settable property, it probably does. But in my experience, questioning the assumption that a property needs to be changeable pays off  consistently, if infrequently.<\/p>\n<h3>Principle 1: Use <code>@synthesize<\/code><\/h3>\n<p>This should go without saying, but as long as I&#8217;m enumerating best-practices: if you are using Objective-C 2.0 (iPhone or Mac OS X 10.5 &#038; up) you should <strong>use <code>@synthesize<\/code>-ed <a href=\"http:\/\/developer.apple.com\/DOCUMENTATION\/Cocoa\/Conceptual\/ObjectiveC\/Articles\/ocProperties.html#\/\/apple_ref\/doc\/uid\/TP30001163-CH17-SW1\">properties<\/a> to implement your setters.<\/strong><\/p>\n<p>The obvious benefits are less code, and setters that are guaranteed to work by the compiler.  A less obvious benefit is <a href=\"http:\/\/cocoawithlove.com\/2008\/08\/in-defense-of-objective-c-20-properties.html\">a clean, abstracted way to expose the state values of an object<\/a>.  Also, <a href=\"http:\/\/vgable.com\/blog\/2008\/12\/20\/automatically-freeing-every-property\/\">using properties can simplify you <code>dealloc<\/code> method<\/a>.<\/p>\n<p>But watch out for the a <a href=\"http:\/\/vgable.com\/blog\/2009\/03\/17\/mutable-property-and-copy-gotcha\/\">gotcha if you are using <code>copy<\/code>-assignment for an <code>NSMutable<\/code> object<\/a>!<\/p>\n<p>(Note: Some Cocoa programmers strongly dislike the dot-syntax that was introduced with properties and lets you say <code>x.foo = 3;<\/code> instead of <code>[x setFoo:3];<\/code>.  But, <strong>you can use properties without using the dot-syntax<\/strong>.  For the record, I think the dot syntax is an improvement.  But don&#8217;t let a hatred of it it keep you from using properties.)<\/p>\n<h3>Principle 2: Prefer <code>copy<\/code> over <code>retain<\/code><\/h3>\n<p><a href=\"http:\/\/vgable.com\/blog\/2008\/11\/14\/prefer-copy-over-retain\/\">I covered this in detail here<\/a>.  In summary, use <code>copy<\/code> over <code>retain<\/code> whenever possible: <strong><code>copy<\/code> is safer<\/strong>, and with most basic Foundation objects, <strong><code>copy<\/code> is just as fast and efficient as <code>retain<\/code>.<\/strong><\/p>\n<h3>The Preferred Pattern<\/h3>\n<p>When properties are unavailable, this is my &#8220;go-to&#8221; pattern:<\/p>\n<pre>\n- (void) setX:(TypeOfX*)newX;\n{\n&nbsp;&nbsp;[memberVariableThatHoldsX autorelease];\n&nbsp;&nbsp;memberVariableThatHoldsX = [newX copy];\n}\n<\/pre>\n<p>Sometimes I use use <code>retain<\/code>, or very rarely <code>mutableCopy<\/code>, instead of <code>copy<\/code>. But if <code>autorelease<\/code> won&#8217;t work, then I use a different pattern. I have a few reasons for writing setters this way.<\/p>\n<h4>Reason: Less Code<\/h4>\n<p>This pattern is only two lines of code, and has <strong>no conditionals<\/strong>.  There is very little that can I can screw up when writing it. It always does the same thing, which simplifies debugging.<\/p>\n<h4>Reason: <code>autorelease<\/code> Defers Destruction<\/h4>\n<p>Using <code>autorelease<\/code> instead of <code>release<\/code> is just a little bit safer, because it does not immediately destroy the old value.<\/p>\n<p>If the old value is immediately released in the setter then this code will sometimes crash,<\/p>\n<pre>\nNSString* oldName = [x name];\n[x setName:@\"Alice\"];\nNSLog(@\"%@ has changed their name to Alice\", oldName);\n<\/pre>\n<p>If <code>-setName:<\/code> immediately releasees the value that <code>-name<\/code> returned, <code>oldName<\/code> will be invalid when it&#8217;s used in <code>NSLog<\/code>.<\/p>\n<p>But if If <code>-setName:<\/code> <code>autorelease<\/code>-ed the old value instead, this wouldn&#8217;t be a problem; <code>oldName<\/code> would still be valid until the current autorelease pool was drained.<\/p>\n<h4>Reason: Precedent<\/h4>\n<p>This is <a href=\"http:\/\/google-styleguide.googlecode.com\/svn\/trunk\/objcguide.xml#Autorelease_Then_Retain\">the pattern that google recommends.<\/a><\/p>\n<blockquote><p>\nWhen assigning a new object to a variable, one must first release the old object to avoid a memory leak. There are several &#8220;correct&#8221; ways to handle this. We&#8217;ve chosen the &#8220;autorelease then retain&#8221; approach because it&#8217;s less prone to error. Be aware in tight loops it can fill up the autorelease pool, and may be slightly less efficient, but we feel the tradeoffs are acceptable.<\/p>\n<pre>- (void)setFoo:(GMFoo *)aFoo {\n  [foo_ autorelease];  \/\/ Won't dealloc if |foo_| == |aFoo|\n  foo_ = [aFoo retain]; \n}\n<\/pre>\n<\/blockquote>\n<h3>Backup Pattern (No <code>autorelease<\/code>)<\/h3>\n<p>When <code>autorelease<\/code> won&#8217;t work, my Plan-B is:<\/p>\n<pre>\n- (void) setX:(TypeOfX*)newX;\n{\n&nbsp;&nbsp;id old = memberVariableThatHoldsX;\n&nbsp;&nbsp;memberVariableThatHoldsX = [newX copy];\n&nbsp;&nbsp;[old release];\n}\n<\/pre>\n<h4>Reason: Simple<\/h4>\n<p>Again, there are no conditionals in this pattern. There&#8217;s no <code>if(oldX != newX)<\/code> test for me to screw up. (Yes, I have done this. It wasn&#8217;t a hard bug to discover and fix, but it was a bug nonetheless.) When I&#8217;m debugging a problem, I <em>know<\/em> exactly what <code>setX:<\/code> did to it&#8217;s inputs, without having to know what they are.<\/p>\n<h4>On <code>id old<\/code><\/h4>\n<p>I like naming my temporary old-value <code>id old<\/code>, because that name &#038; type <em>always<\/em> works, and it&#8217;s short. It&#8217;s less to type, and less to think about than <code>TypeOfX* oldX<\/code>.<\/p>\n<p>But I don&#8217;t think it&#8217;s necessarily the best choice for doing more to <code>old<\/code> than sending it <code>release<\/code>.<\/p>\n<p>To be honest I&#8217;m still evaluating that naming practice.  But so far I&#8217;ve been happy with it.<\/p>\n<h3>Principle 3: Only Optimize <em>After<\/em> You Measure<\/h3>\n<p>This is an old maxim of Computer Science, but it bears repeating.<\/p>\n<p>The most common pattern for a setter feels like premature optimization:<\/p>\n<pre>- (void) setX:(TypeOfX*)newX;\n{\n&nbsp;&nbsp;if(newX != memberVariableThatHoldsX){\n&nbsp;&nbsp;&nbsp;&nbsp;[memberVariableThatHoldsX release];\n&nbsp;&nbsp;&nbsp;&nbsp;memberVariableThatHoldsX = [newX copy];\n&nbsp;&nbsp;}\n}\n<\/pre>\n<p>Testing <code>if(newX != memberVariableThatHoldsX)<\/code> can avoid an expensive <code>copy<\/code>.<\/p>\n<p>But it also slows <em>every<\/em> call to <code>setX:<\/code>.  <code>if<\/code> statements are more code, that takes time to execute.  When the processor <a href=\"http:\/\/en.wikipedia.org\/wiki\/Branch_prediction\">guesses wrong<\/a> while loading instructions after the branch, <code>if<\/code>&#8216;s become <a href=\"http:\/\/en.wikipedia.org\/wiki\/Instruction_pipeline#Complications\">quite expensive<\/a>.<\/p>\n<p>To know what way is faster, you have to measure real-world conditions. Even if a <code>copy<\/code> is  <em>very<\/em> slow, the conditional approach isn&#8217;t necessarily faster, unless there is code that sets a property to it&#8217;s current value.  Which is kind of silly really.  How often do you write code like,<\/p>\n<pre>[a setX:x1];\n[a setX:x1]; \/\/just to be sure!<\/pre>\n<p>or<\/p>\n<pre>[a setX:[a x]];<\/pre>\n<p>Does that look like code you want to optimize? (Trick question! You don&#8217;t know until you test.)<\/p>\n<h4>Hypocrisy!<\/h4>\n<p>I constantly break Principle 3 by declaring properties in <em>iPhone<\/em> code as <code>nonatomic<\/code>, since it&#8217;s the pattern Apple uses in their libraries. I assume Apple has good reason for it; and since I will need to write synchronization-code to safely use <em>their<\/em> libraries, I figure it&#8217;s not much more work to reuse the same code to protect access to my objects.<\/p>\n<p>I can&#8217;t shake the feeling I&#8217;m wrong to do this.  But it seems more wrong to not follow Apple&#8217;s example; they wrote the iPhone OS in the first place.<\/p>\n<h3>If you know a better best practice, say so!<\/h3>\n<p>There isn&#8217;t a way to write a setter that works optimally <em>all<\/em> the time, but there is a setter-pattern that works optimally more often then other patterns. With your help I can find it.<\/p>\n<h4>UPDATE 03-30-2009:<\/h4>\n<p> <a href=\"http:\/\/www.wilshipley.com\/blog\/2005\/07\/code-insults-mark-i.html\">Wil Shiply disagrees<\/a>.  Essentially his argument is that setters are called a lot, so if they aren&#8217;t aggressive about freeing memory, you can have thousands of dead objects rotting in an autorelease pool. Plus, setters often do things like registering with the undo manager, and that&#8217;s expensive, so it&#8217;s a good idea to have conditional code that only does that when necessary.<\/p>\n<p>My rebuttal is that you should optimize big programs by draining autorelease pools early anyway; and that mitigates the dead-object problem.<\/p>\n<p>With complex setters I can see why it makes sense to check if you <em>need<\/em> to do something before doing it. I still prefer safer, unconditional, code as a <em>simple first implementation<\/em>. That&#8217;s why it&#8217;s my go-to pattern. But if most setters you write end up being more complex, it might be the wrong pattern.<\/p>\n<p>Really you should <a href=\"http:\/\/www.wilshipley.com\/blog\/2005\/07\/code-insults-mark-i.html\">read what Wil says<\/a>, and decide for yourself. He&#8217;s got much more experience with Objective-C development then I do.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are several ways to write setters for Objective-C\/Cocoa objects that work. But here are the practices I follow; to the best of my knowledge they produce the safest code. Principle 0: Don&#8217;t Write a Setter When possible, it&#8217;s best to write immutable objects. Generally they are safer, and easier to optimize, especially when it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,6,203,3,5,4,13],"tags":[376,241,616,279,224,174,375],"class_list":["post-285","post","type-post","status-publish","format-standard","hentry","category-bug-bite","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\/285","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=285"}],"version-history":[{"count":0,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/285\/revisions"}],"wp:attachment":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/media?parent=285"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/categories?post=285"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/tags?post=285"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}