<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Singletons in Cocoa: Doing them wrong</title>
	<atom:link href="http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/feed" rel="self" type="application/rss+xml" />
	<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong</link>
	<description>The personal weblog of Peter Hosey.</description>
	<lastBuildDate>Tue, 07 Sep 2010 04:42:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-331763</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Sat, 04 Sep 2010 13:12:53 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-331763</guid>
		<description>Kendall Helmstetter Gelner:

&lt;blockquote&gt;Lets say you get someone who knows memory management pretty well but forgets they are using a singleton class. So, they alloc/init and then when done they call release. Again, the running code comes back sometime later to the same point and calls alloc/init again....

They are screwed, even though they followed the correct memory management rules. Because you did not override release, the shared instance variable you check in init is not nil, but is now invalid!&lt;/blockquote&gt;

No, it&#039;s still a valid object, because the singleton owns itself.

There may actually be a bug along those lines in the implementation shown above, though. I really need to put this into version control and write a bunch of tests for it.

&lt;blockquote&gt;I would argue if you are going to override release you may as well do retain as well to match, to keep the retain count at the value you would expect a singleton to have.&lt;/blockquote&gt;

Correct. If you do override them, you should also override &lt;code&gt;retainCount&lt;/code&gt;, to return &lt;code&gt;UINT_MAX&lt;/code&gt;.</description>
		<content:encoded><![CDATA[<p>Kendall Helmstetter Gelner:</p>
<blockquote cite="http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong#comment-"><p>Lets say you get someone who knows memory management pretty well but forgets they are using a singleton class. So, they alloc/init and then when done they call release. Again, the running code comes back sometime later to the same point and calls alloc/init again....</p>
<p>They are screwed, even though they followed the correct memory management rules. Because you did not override release, the shared instance variable you check in init is not nil, but is now invalid!</p>
</blockquote>
<p>No, it's still a valid object, because the singleton owns itself.</p>
<p>There may actually be a bug along those lines in the implementation shown above, though. I really need to put this into version control and write a bunch of tests for it.</p>
<blockquote cite="http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong#comment-"><p>I would argue if you are going to override release you may as well do retain as well to match, to keep the retain count at the value you would expect a singleton to have.</p>
</blockquote>
<p>Correct. If you do override them, you should also override <code>retainCount</code>, to return <code>UINT_MAX</code>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kendall Helmstetter Gelner</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-301752</link>
		<dc:creator>Kendall Helmstetter Gelner</dc:creator>
		<pubDate>Fri, 05 Feb 2010 21:07:37 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-301752</guid>
		<description>I have to disagree on the whole retain/release thing.

Your whole argument about leaving it out is that you are &quot;hiding bugs&quot;.  But if you override retain/release, by definition it is not a bug to call release on that object, you have changed the meaning for the class in a way that is compatible with the understanding the developer would have about how retain/release work.

Instead what you are doing, is making your application less robust and purposefully introducing a single point of failure that will probably lead to a crash.   You are trying to make the code outside your class a little better, at the cost of potential frustration to the application owner who should at all times be paramount in your thoughts as an application developer.

The trouble is you think you are protecting bad coders from themselves but instead you are spreading code with a very nasty subtle bug that might well be overlooked by many programmers.  What happens if in testing they only make use of the singleton once, and then call release?  Everything works of course because the invalid reference is never used.  But then the application reaches the real world, and the infrequently used singleton is finally accessed twice... you have not helped the poor developer at all, you have introduced a crashing bug to thousands of users and forced the developer to learn all about desymbolication.

In fact you aren&#039;t even putting just bad coders in peril.  Lets say you get someone who knows memory management pretty well but forgets they are using a singleton class.  So, they alloc/init and then when done they call release.  Again, the running code comes back sometime later to the same point and calls alloc/init again....

They are screwed, even though they followed the correct memory management rules.  Because you did not override release, the shared instance variable you check in init is not nil, but is now invalid!   So your init code proceeds to return the now invalid instance, and crashing ensues.  What did they do to deserve this cruel trick?  They were again decent developers following the memory management rules, the only crime was that they did not read the source for the class they tried to use.

At the very minimum, you should override release to throw an exception in debug mode only and not actually release the object.  Then the application will work, but any accidental or misguided release calls to the singleton will flag the error to the developer, not the application owner. This gives you the effect of developer guidance you were seeking without peril to the continued operation of the application.  

I would argue if you are going to override release you may as well do retain as well to match, to keep the retain count at the value you would expect a singleton to have.  But that part I am far more indifferent to since it doesn&#039;t really affect execution the way mishandling release can.</description>
		<content:encoded><![CDATA[<p>I have to disagree on the whole retain/release thing.</p>
<p>Your whole argument about leaving it out is that you are "hiding bugs".  But if you override retain/release, by definition it is not a bug to call release on that object, you have changed the meaning for the class in a way that is compatible with the understanding the developer would have about how retain/release work.</p>
<p>Instead what you are doing, is making your application less robust and purposefully introducing a single point of failure that will probably lead to a crash.   You are trying to make the code outside your class a little better, at the cost of potential frustration to the application owner who should at all times be paramount in your thoughts as an application developer.</p>
<p>The trouble is you think you are protecting bad coders from themselves but instead you are spreading code with a very nasty subtle bug that might well be overlooked by many programmers.  What happens if in testing they only make use of the singleton once, and then call release?  Everything works of course because the invalid reference is never used.  But then the application reaches the real world, and the infrequently used singleton is finally accessed twice... you have not helped the poor developer at all, you have introduced a crashing bug to thousands of users and forced the developer to learn all about desymbolication.</p>
<p>In fact you aren't even putting just bad coders in peril.  Lets say you get someone who knows memory management pretty well but forgets they are using a singleton class.  So, they alloc/init and then when done they call release.  Again, the running code comes back sometime later to the same point and calls alloc/init again....</p>
<p>They are screwed, even though they followed the correct memory management rules.  Because you did not override release, the shared instance variable you check in init is not nil, but is now invalid!   So your init code proceeds to return the now invalid instance, and crashing ensues.  What did they do to deserve this cruel trick?  They were again decent developers following the memory management rules, the only crime was that they did not read the source for the class they tried to use.</p>
<p>At the very minimum, you should override release to throw an exception in debug mode only and not actually release the object.  Then the application will work, but any accidental or misguided release calls to the singleton will flag the error to the developer, not the application owner. This gives you the effect of developer guidance you were seeking without peril to the continued operation of the application.  </p>
<p>I would argue if you are going to override release you may as well do retain as well to match, to keep the retain count at the value you would expect a singleton to have.  But that part I am far more indifferent to since it doesn't really affect execution the way mishandling release can.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-299315</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Sun, 10 Jan 2010 20:03:11 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-299315</guid>
		<description>I see your meaning now. Thanks. I think I&#039;ll put this whole thing in an Xcode project in version control to handle changes like this in the future (and make adoption easier). I&#039;ll probably do this before CocoaHeads this week.</description>
		<content:encoded><![CDATA[<p>I see your meaning now. Thanks. I think I'll put this whole thing in an Xcode project in version control to handle changes like this in the future (and make adoption easier). I'll probably do this before CocoaHeads this week.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christiaan Hofman</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-299296</link>
		<dc:creator>Christiaan Hofman</dc:creator>
		<pubDate>Sun, 10 Jan 2010 18:18:51 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-299296</guid>
		<description>I disagree completely. You should look at memory management rules locally, as Clang also does, and then everything works out naturally an correctly.

The point is that in &lt;code&gt;sharedInstance = self&lt;/code&gt;, the &lt;code&gt;sharedInstance&lt;/code&gt; is assigned and ownership is passed to the class, which means that the instance must be explicitly retained. In your code this extra retain count comes from the line in &lt;code&gt;+initialize&lt;/code&gt;, which is wrong, because that&#039;s not the point where ownership is passed (the shared instance is assigned). The line &lt;code&gt;[[self alloc] init]&lt;/code&gt; has a net retain count of 1, but there&#039;s no assignment, so nobody taking ownership. Therefore it goes against the memory management rules. To make this more obvious, think of introducing a setter method &lt;code&gt;+setSharedInstance:&lt;/code&gt; to assign the shared instance; the implementation of that method should contain a &lt;code&gt;retain&lt;/code&gt; as is normal for a setter. Just do the count when you follow my recommendations (all three of them). 

As for the line &lt;code&gt;self = sharedInstance&lt;/code&gt;, remember that &lt;code&gt;self&lt;/code&gt; should have a retain count of one coming from the creation independent of what else happens, that is, not counting the global retain count of 1 for the shared instance. This means that it needs one extra &lt;code&gt;retain&lt;/code&gt;. Think about when somehow the code would go through this line as it is now: in that case the retain count for &lt;code&gt;sharedInstance&lt;/code&gt; would be the same, even though an &lt;code&gt;alloc/init&lt;/code&gt; is used to get it, so a following &lt;code&gt;release&lt;/code&gt; on the returned object &lt;em&gt;should&lt;/em&gt; be valid. Let me rephrase this. Using &lt;code&gt;[[[PRHEmptySingleton alloc] init] release]&lt;/code&gt; should be OK. However, if for some reason this would use the last part (for the sake of the argument), then this would lead to the retain count of &lt;code&gt;sharedInstance&lt;/code&gt; to be reduced by one, and it would become invalid. 

In short, this is the correct code.

&lt;pre&gt;+ (void) initialize {
    if (!sharedInstance) {
        // Nobody takes ownership here, so retain count should be balanced to 0
        [[[self alloc] init] release];
    }
}

+ (id) sharedFramistan {
    return sharedInstance;
}

+ (id) allocWithZone:(NSZone *)zone {
    // We should have one more overall retain because it&#039;s alloc
    return [sharedInstance retain] ?: [super allocWithZone:zone];
}

- (id) init {
    if (!sharedInstance) {
        if ((self = [super init])) {
            //Initialize the instance here.
        }
        // The class takes ownership over sharedInstance here, so retain explicitly, think of a setter, think of replacing it with
        // [[self class] setSharedInstance:self];
        sharedInstance = [self retain];
    } else if (self != sharedInstance) {
        // We reduce overall a retain count here...
        [self release];
        // ...so we need to balance with an extra retain count here. We should be allowed to follow this method with a further retain.
        self = [sharedInstance retain];
    }

    return self;
}&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<p>I disagree completely. You should look at memory management rules locally, as Clang also does, and then everything works out naturally an correctly.</p>
<p>The point is that in <code>sharedInstance = self</code>, the <code>sharedInstance</code> is assigned and ownership is passed to the class, which means that the instance must be explicitly retained. In your code this extra retain count comes from the line in <code>+initialize</code>, which is wrong, because that's not the point where ownership is passed (the shared instance is assigned). The line <code>[[self alloc] init]</code> has a net retain count of 1, but there's no assignment, so nobody taking ownership. Therefore it goes against the memory management rules. To make this more obvious, think of introducing a setter method <code>+setSharedInstance:</code> to assign the shared instance; the implementation of that method should contain a <code>retain</code> as is normal for a setter. Just do the count when you follow my recommendations (all three of them). </p>
<p>As for the line <code>self = sharedInstance</code>, remember that <code>self</code> should have a retain count of one coming from the creation independent of what else happens, that is, not counting the global retain count of 1 for the shared instance. This means that it needs one extra <code>retain</code>. Think about when somehow the code would go through this line as it is now: in that case the retain count for <code>sharedInstance</code> would be the same, even though an <code>alloc/init</code> is used to get it, so a following <code>release</code> on the returned object <em>should</em> be valid. Let me rephrase this. Using <code>[[[PRHEmptySingleton alloc] init] release]</code> should be OK. However, if for some reason this would use the last part (for the sake of the argument), then this would lead to the retain count of <code>sharedInstance</code> to be reduced by one, and it would become invalid. </p>
<p>In short, this is the correct code.</p>
<pre>+ (void) initialize {
    if (!sharedInstance) {
        // Nobody takes ownership here, so retain count should be balanced to 0
        [[[self alloc] init] release];
    }
}

+ (id) sharedFramistan {
    return sharedInstance;
}

+ (id) allocWithZone:(NSZone *)zone {
    // We should have one more overall retain because it's alloc
    return [sharedInstance retain] ?: [super allocWithZone:zone];
}

- (id) init {
    if (!sharedInstance) {
        if ((self = [super init])) {
            //Initialize the instance here.
        }
        // The class takes ownership over sharedInstance here, so retain explicitly, think of a setter, think of replacing it with
        // [[self class] setSharedInstance:self];
        sharedInstance = [self retain];
    } else if (self != sharedInstance) {
        // We reduce overall a retain count here...
        [self release];
        // ...so we need to balance with an extra retain count here. We should be allowed to follow this method with a further retain.
        self = [sharedInstance retain];
    }

    return self;
}</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-299268</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Sun, 10 Jan 2010 12:21:03 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-299268</guid>
		<description>&lt;blockquote&gt;In -init you have two assignments that are not properly retained.&lt;/blockquote&gt;

More like properly not retained. If the caller goes directly to &lt;code&gt;alloc&lt;/code&gt;/&lt;code&gt;init&lt;/code&gt; instead of going through &lt;code&gt;sharedInstance&lt;/code&gt;, retaining the receiver in &lt;code&gt;init&lt;/code&gt; will over-retain it (implicit retain by &lt;code&gt;alloc&lt;/code&gt; + explicit &lt;code&gt;retain&lt;/code&gt; in &lt;code&gt;init&lt;/code&gt;). Thus, explicitly retaining in &lt;code&gt;init&lt;/code&gt; is not an option if I want to maintain compatibility with the &lt;code&gt;alloc&lt;/code&gt;/&lt;code&gt;init&lt;/code&gt; path. Without explicitly retaining in &lt;code&gt;init&lt;/code&gt;, an &lt;code&gt;autorelease&lt;/code&gt; in &lt;code&gt;sharedInstance&lt;/code&gt; would probably be the final release and would cause the object&#039;s death.

I&#039;m not sure what to do about the Clang warnings. Second static variable, perhaps? (Using the first one in both places would probably beget a dead store warning.)</description>
		<content:encoded><![CDATA[<blockquote cite="http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong#comment-"><p>In -init you have two assignments that are not properly retained.</p>
</blockquote>
<p>More like properly not retained. If the caller goes directly to <code>alloc</code>/<code>init</code> instead of going through <code>sharedInstance</code>, retaining the receiver in <code>init</code> will over-retain it (implicit retain by <code>alloc</code> + explicit <code>retain</code> in <code>init</code>). Thus, explicitly retaining in <code>init</code> is not an option if I want to maintain compatibility with the <code>alloc</code>/<code>init</code> path. Without explicitly retaining in <code>init</code>, an <code>autorelease</code> in <code>sharedInstance</code> would probably be the final release and would cause the object's death.</p>
<p>I'm not sure what to do about the Clang warnings. Second static variable, perhaps? (Using the first one in both places would probably beget a dead store warning.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christiaan Hofman</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-299267</link>
		<dc:creator>Christiaan Hofman</dc:creator>
		<pubDate>Sun, 10 Jan 2010 11:52:12 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-299267</guid>
		<description>Peter, you can still improve on your code, because it now does not properly follow the memory management rules locally. As a result, Clang will give warnings. In &lt;code&gt;+initialize&lt;/code&gt; you have a retained object without assignment, so to follow the rules you should add an extra &lt;code&gt;autorelease&lt;/code&gt;. In &lt;code&gt;-init&lt;/code&gt; you have two assignments that are not properly retained. So the assignment of &lt;code&gt;sharedInstance&lt;/code&gt; should read &lt;code&gt;sharedInstance = [self retain];&lt;/code&gt;, as this is the place where the class will take ownership of this instance. Also, the opposite assignment later on should read &lt;code&gt;self = [sharedInstance retain];&lt;/code&gt;, the extra &lt;code&gt;retain&lt;/code&gt; essentially balances the &lt;code&gt;release&lt;/code&gt; in the line above it. Of course this code path should actually never be called. 

And the code in &lt;code&gt;+initialize&lt;/code&gt; could easily go into &lt;code&gt;+sharedInstance&lt;/code&gt; for lazy evaluation.</description>
		<content:encoded><![CDATA[<p>Peter, you can still improve on your code, because it now does not properly follow the memory management rules locally. As a result, Clang will give warnings. In <code>+initialize</code> you have a retained object without assignment, so to follow the rules you should add an extra <code>autorelease</code>. In <code>-init</code> you have two assignments that are not properly retained. So the assignment of <code>sharedInstance</code> should read <code>sharedInstance = [self retain];</code>, as this is the place where the class will take ownership of this instance. Also, the opposite assignment later on should read <code>self = [sharedInstance retain];</code>, the extra <code>retain</code> essentially balances the <code>release</code> in the line above it. Of course this code path should actually never be called. </p>
<p>And the code in <code>+initialize</code> could easily go into <code>+sharedInstance</code> for lazy evaluation.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-297568</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Thu, 17 Dec 2009 18:55:34 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-297568</guid>
		<description>&lt;blockquote&gt;I want to display custom alerts that can be controlled with the Apple Remote, while [the app] is in fullscreen mode.&lt;/blockquote&gt;

This implies that it can be switched in and out of full-screen mode. Is that correct?</description>
		<content:encoded><![CDATA[<blockquote cite="http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong#comment-"><p>I want to display custom alerts that can be controlled with the Apple Remote, while [the app] is in fullscreen mode.</p>
</blockquote>
<p>This implies that it can be switched in and out of full-screen mode. Is that correct?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Uli Kusterer</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-297549</link>
		<dc:creator>Uli Kusterer</dc:creator>
		<pubDate>Thu, 17 Dec 2009 14:11:09 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-297549</guid>
		<description>Peter, one more suggestion: One of the uses for Singletons is that you can have a project-specific subclass of a singleton (if you don&#039;t need that, why bother with a specially-implemented signleton? Why not just use a class with class methods?).

E.g. I have an &quot;alert manager&quot; singleton that my code uses to show error messages. One app has a fullscreen mode where I want to display custom alerts that can be controlled with the Apple Remote, while it is in fullscreen mode. So I create a fullscreen alert manager subclass that knows the specific fullscreen stuff for that one app. All code just asks for [MyAlertManager sharedManager]. In the main() function of the fullscreen app, I do a [MyFullscreenAwareAlertManager sharedManager]. Since this is called first, the alert manager singleton is actually an instance of the subclass. All calls to the superclass in shared code modules now transparently end up with the subclass instead Shared code doesn&#039;t need to be aware of fullscreen support, no ugly ifdefs, no unnecessary dependencies on the fullscreen display code of one app in other apps.

For this to work, I can&#039;t use the +initialize method you have here (because the superclass&#039;s initialize always gets called before the subclass), instead, I&#039;m doing that work in my sharedManager method. I use [self class] so the subclass automatically inits a subclass instance.

The only disadvantage of this technique is if other code accidentally refers to a third subclass of the base class first, my calls to the second subclass will go to the wrong kind of object.</description>
		<content:encoded><![CDATA[<p>Peter, one more suggestion: One of the uses for Singletons is that you can have a project-specific subclass of a singleton (if you don't need that, why bother with a specially-implemented signleton? Why not just use a class with class methods?).</p>
<p>E.g. I have an "alert manager" singleton that my code uses to show error messages. One app has a fullscreen mode where I want to display custom alerts that can be controlled with the Apple Remote, while it is in fullscreen mode. So I create a fullscreen alert manager subclass that knows the specific fullscreen stuff for that one app. All code just asks for [MyAlertManager sharedManager]. In the main() function of the fullscreen app, I do a [MyFullscreenAwareAlertManager sharedManager]. Since this is called first, the alert manager singleton is actually an instance of the subclass. All calls to the superclass in shared code modules now transparently end up with the subclass instead Shared code doesn't need to be aware of fullscreen support, no ugly ifdefs, no unnecessary dependencies on the fullscreen display code of one app in other apps.</p>
<p>For this to work, I can't use the +initialize method you have here (because the superclass's initialize always gets called before the subclass), instead, I'm doing that work in my sharedManager method. I use [self class] so the subclass automatically inits a subclass instance.</p>
<p>The only disadvantage of this technique is if other code accidentally refers to a third subclass of the base class first, my calls to the second subclass will go to the wrong kind of object.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Uli Kusterer</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-290667</link>
		<dc:creator>Uli Kusterer</dc:creator>
		<pubDate>Sat, 19 Sep 2009 17:17:06 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-290667</guid>
		<description>Just thought I&#039;d mention that Peter has pointed out this posting in a comment to my article on &lt;a href=&quot;http://www.zathras.de/blog-defensive-coding-in-objective-c.htm&quot; rel=&quot;nofollow&quot;&gt;Defensive coding in Objective C&lt;/a&gt; and we&#039;re working out a few more details of this code there. The curious among the uninterested might wanna check that out.</description>
		<content:encoded><![CDATA[<p>Just thought I'd mention that Peter has pointed out this posting in a comment to my article on <a href="http://www.zathras.de/blog-defensive-coding-in-objective-c.htm" rel="nofollow">Defensive coding in Objective C</a> and we're working out a few more details of this code there. The curious among the uninterested might wanna check that out.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-289540</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Sat, 05 Sep 2009 02:18:37 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-289540</guid>
		<description>Christiaan Hofman: Ah, I see now. You&#039;re right, and I apologize.

To keep your comments in context, here&#039;s a record of what the code said:

&lt;pre&gt;+ (void) initialize {
    if (!sharedInstance)
        sharedInstance = [[self alloc] init];
}

- (id) init {
    if (!hasInited) {
        if ((self = [super init])) {
            //Initialize the instance here.

            hasInited = YES;
        }
    }

    return self;
}&lt;/pre&gt;

&lt;code&gt;hasInited&lt;/code&gt; was an instance variable.</description>
		<content:encoded><![CDATA[<p>Christiaan Hofman: Ah, I see now. You're right, and I apologize.</p>
<p>To keep your comments in context, here's a record of what the code said:</p>
<pre>+ (void) initialize {
    if (!sharedInstance)
        sharedInstance = [[self alloc] init];
}

- (id) init {
    if (!hasInited) {
        if ((self = [super init])) {
            //Initialize the instance here.

            hasInited = YES;
        }
    }

    return self;
}</pre>
<p><code>hasInited</code> was an instance variable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christiaan Hofman</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-289439</link>
		<dc:creator>Christiaan Hofman</dc:creator>
		<pubDate>Fri, 04 Sep 2009 11:48:10 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-289439</guid>
		<description>Peter: Well, it&#039;s assigned in +initialize. This is the first thing that happens, but the assignment takes place after the initial call to -init (because a fully initialized instance is assigned). This means that the first instance that&#039;s allocated and initialized is guaranteed to be the one that will be assigned to sharedInstance, while it is also guaranteed that sharedInstance is assigned whenever another explicit call to +sharedInstance, +allocWithZone: or -init is executed. You think about that.</description>
		<content:encoded><![CDATA[<p>Peter: Well, it's assigned in +initialize. This is the first thing that happens, but the assignment takes place after the initial call to -init (because a fully initialized instance is assigned). This means that the first instance that's allocated and initialized is guaranteed to be the one that will be assigned to sharedInstance, while it is also guaranteed that sharedInstance is assigned whenever another explicit call to +sharedInstance, +allocWithZone: or -init is executed. You think about that.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-289425</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Fri, 04 Sep 2009 08:40:12 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-289425</guid>
		<description>&lt;blockquote&gt;You could make it even simpler. The hasInited ivar is totally unnecessary, you can just as well check whether sharedInstance is nil. Think about it.&lt;/blockquote&gt;

Think about this: Where is &lt;code&gt;sharedInstance&lt;/code&gt; assigned?</description>
		<content:encoded><![CDATA[<blockquote cite="http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong#comment-"><p>You could make it even simpler. The hasInited ivar is totally unnecessary, you can just as well check whether sharedInstance is nil. Think about it.</p>
</blockquote>
<p>Think about this: Where is <code>sharedInstance</code> assigned?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christiaan Hofman</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-289292</link>
		<dc:creator>Christiaan Hofman</dc:creator>
		<pubDate>Thu, 03 Sep 2009 13:01:32 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-289292</guid>
		<description>You could make it even simpler. The hasInited ivar is totally unnecessary, you can just as well check whether sharedInstance is nil. Think about it.

Also what I miss in your discussion is the reason why you need to override init. The reason is that when you need to instantiate an instance in a NIB, the NIB loader will always use alloc/init, it won&#039;t be using your custom class factory method. Of course in code you should always use the class factory method.</description>
		<content:encoded><![CDATA[<p>You could make it even simpler. The hasInited ivar is totally unnecessary, you can just as well check whether sharedInstance is nil. Think about it.</p>
<p>Also what I miss in your discussion is the reason why you need to override init. The reason is that when you need to instantiate an instance in a NIB, the NIB loader will always use alloc/init, it won't be using your custom class factory method. Of course in code you should always use the class factory method.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sean</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-285938</link>
		<dc:creator>Sean</dc:creator>
		<pubDate>Mon, 03 Aug 2009 04:01:30 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-285938</guid>
		<description>Peter: I&#039;m pretty sure the docs are wrong, many of them are still not fully updated for 64 bit.  A similar example: NSNotFound.  The docs still show 0x7fffffff, but the .h changed from INT_MAX to NSIntegerMax.  And sample code gets way less love than the docs.</description>
		<content:encoded><![CDATA[<p>Peter: I'm pretty sure the docs are wrong, many of them are still not fully updated for 64 bit.  A similar example: NSNotFound.  The docs still show 0x7fffffff, but the .h changed from INT_MAX to NSIntegerMax.  And sample code gets way less love than the docs.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Hosey</title>
		<link>http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong/comment-page-1#comment-283327</link>
		<dc:creator>Peter Hosey</dc:creator>
		<pubDate>Sat, 11 Jul 2009 03:03:26 +0000</pubDate>
		<guid isPermaLink="false">http://boredzo.org/blog/?p=1034#comment-283327</guid>
		<description>Sean: Not according to the NSObject documentation. It explicitly says UINT_MAX.

It&#039;s possible that they&#039;re both wrong. You should file a documentation bug.</description>
		<content:encoded><![CDATA[<p>Sean: Not according to the NSObject documentation. It explicitly says UINT_MAX.</p>
<p>It's possible that they're both wrong. You should file a documentation bug.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.427 seconds -->
