<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>mikeash.com pyblog/friday-qa-2013-01-25-lets-build-nsobject.html comments</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>mikeash.com Recent Comments</description><lastBuildDate>Sun, 12 Apr 2026 02:25:16 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Aka Contacts - 2014-11-12 15:12:03</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>The is one of the best posts on the very basic of iPhone programming. Initially, I have no ideal on what NSObject does, but now I have a rough impression. Thanks for the great write up</description><guid isPermaLink="true">2001f0e19de1fd92f53412ebdb812411</guid><pubDate>Wed, 12 Nov 2014 15:12:03 GMT</pubDate></item><item><title>mikeash - 2013-02-07 14:52:04</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>&lt;code&gt;oneway&lt;/code&gt; is a modifier used for Distributed Objects. It says that the caller doesn't need to wait for the method to complete before proceeding, as it has no callee-visible side effects. It's an optimization, and one that doesn't make much difference these days, as DO isn't much used, and especially not in places where the latency of waiting for a call like this to complete would make a difference.</description><guid isPermaLink="true">03f6f2c439351d0736947b788a131646</guid><pubDate>Thu, 07 Feb 2013 14:52:04 GMT</pubDate></item><item><title>Ariel Feinerman - 2013-02-07 13:08:55</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>What is a oneway in the -release name ?</description><guid isPermaLink="true">e6abfbafe3fa5fc9080a4107fc4f0168</guid><pubDate>Thu, 07 Feb 2013 13:08:55 GMT</pubDate></item><item><title>Ariel Feinerman - 2013-02-07 11:52:08</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>I use the -retainCount to see the memory leaks in objects with many levels of hierarchy for instance 
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;</description><guid isPermaLink="true">c50ca00098135dd277ebef804b89b556</guid><pubDate>Thu, 07 Feb 2013 11:52:08 GMT</pubDate></item><item><title>Ariel Feinerman - 2013-02-07 11:42:50</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Mike, you write that +allocWithZone: is deprecated but as far as I know for backward compatibility +alloc and -copy all call the allocWithZone: and copyWithZone:  </description><guid isPermaLink="true">b0a338028482688093786bf6e9ec7469</guid><pubDate>Thu, 07 Feb 2013 11:42:50 GMT</pubDate></item><item><title>mikeash - 2013-02-02 00:34:31</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>The perils of writing your own blog software. The &amp;lt;&amp;gt; &lt;i&gt;is&lt;/i&gt; encoded in there, but for reasons as yet unknown to me, it needs to be double-encoded (e.g. &amp;amp;amp;lt;). I extra encoding until I can figure out what's going on there. Thanks for the tip.</description><guid isPermaLink="true">c91eac6ff92b482351dcd14728c55b9b</guid><pubDate>Sat, 02 Feb 2013 00:34:31 GMT</pubDate></item><item><title>SSteve - 2013-02-01 22:24:05</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>&lt;div class="blogcommentquote"&gt;&lt;div class="blogcommentquoteinner"&gt;generates a string of the form ,&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;You need some &lt;code&gt;lt&lt;/code&gt; and &lt;code&gt;gt&lt;/code&gt; encoding action inside that &lt;code&gt;code&lt;/code&gt; element.</description><guid isPermaLink="true">8d12685144299f228285112864b6b192</guid><pubDate>Fri, 01 Feb 2013 22:24:05 GMT</pubDate></item><item><title>Kyle S - 2013-01-30 08:13:34</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Perhaps there's hope yet of fusing `id` and `&amp;lt;NSObject&amp;gt;`…</description><guid isPermaLink="true">e6186b96dd3664edd7fba347af067bce</guid><pubDate>Wed, 30 Jan 2013 08:13:34 GMT</pubDate></item><item><title>George - 2013-01-29 16:42:28</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Hey, thanks for sharing. It's super simple, and i got a clean understanding of what's going under the hood.
&lt;br /&gt;
&lt;br /&gt;It'd be great to complement this with the ObjC's runtime code, though.
&lt;br /&gt;
&lt;br /&gt;Thanks!
&lt;br /&gt;</description><guid isPermaLink="true">317ba8693cc9fd90d075be757d7abdc3</guid><pubDate>Tue, 29 Jan 2013 16:42:28 GMT</pubDate></item><item><title>bbum - 2013-01-28 17:13:33</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@chrisd NSObject was moved into the runtime because a number of system types well below Foundation (CF, really, as CF has a lot of stuff implemented in ObjC) are now instantiated as Objective-C objects in an opaque, but compatible with ARC, fashion.
&lt;br /&gt;
&lt;br /&gt;SInce these types -- XPC and GCD related objects -- are in libSystem, the ObjC runtime now vends the required pieces directly such that libSystem can exploit these features without depending on CF or above.
&lt;br /&gt;
&lt;br /&gt;See:
&lt;br /&gt;
&lt;br /&gt;&lt;a href="http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h"&gt;http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h&lt;/a&gt;
&lt;br /&gt;</description><guid isPermaLink="true">faa0fc31f8ea55842d48d27029741e03</guid><pubDate>Mon, 28 Jan 2013 17:13:33 GMT</pubDate></item><item><title>chrisd - 2013-01-27 14:46:08</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Looks like newer versions of the objc runtime source include NSObject's implementation. Not sure why... &lt;a href="http://www.opensource.apple.com/source/objc4/objc4-532/runtime/NSObject.mm"&gt;http://www.opensource.apple.com/source/objc4/objc4-532/runtime/NSObject.mm&lt;/a&gt;</description><guid isPermaLink="true">1900466be1a4e7f9be7f8efb9908c839</guid><pubDate>Sun, 27 Jan 2013 14:46:08 GMT</pubDate></item><item><title>Bryan - 2013-01-27 08:04:03</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>performSelector:withObject: should handle the case where the parameter is primitive type by unwrap NSNumber or NSValue and pass it to the actual implementation</description><guid isPermaLink="true">b07609f5fd7eb6ed9d7819642f29876f</guid><pubDate>Sun, 27 Jan 2013 08:04:03 GMT</pubDate></item><item><title>Brad - 2013-01-26 22:20:24</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>"Why was retainCount ever made part of the interface?"
&lt;br /&gt;
&lt;br /&gt;A pessimist might suggest that you have to go back to NeXT and start rounding up engineers if you want to find the guilty party for that decision.  The snarky answer would be "It was the 90's.  It seemed like a good idea at the time, just like the fashions did."
&lt;br /&gt;</description><guid isPermaLink="true">99273bfa3e58034a677e18babd343045</guid><pubDate>Sat, 26 Jan 2013 22:20:24 GMT</pubDate></item><item><title>Jean-Daniel - 2013-01-25 23:19:12</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@bob "retainCount reflects the number of retains and releases"
&lt;br /&gt;
&lt;br /&gt;Unless this is a tagged pointer, a literal constant (@"string"), a cached NSMachPort returned with a retain count indefinite from -(id)initWirhPort:, a cached CFNumberRef, ….
&lt;br /&gt;
&lt;br /&gt;So, yes this method may be useful for very specific case where you get the full control of the object implementation, and the object is not shared among thread, but I think all these exceptions are enough to call it non-deterministic, and unreliable.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><guid isPermaLink="true">ab99546129613f8f2fb4aade67b34c39</guid><pubDate>Fri, 25 Jan 2013 23:19:12 GMT</pubDate></item><item><title>jamie - 2013-01-25 22:33:51</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Why was retainCount ever made part of the interface?
&lt;br /&gt;
&lt;br /&gt;The only client that can make any use of it would be `self`, and it only cares that it's nonzero.  It screams "No User-Serviceable Parts Inside"</description><guid isPermaLink="true">903edb87650059275e91bdd8dbc905f5</guid><pubDate>Fri, 25 Jan 2013 22:33:51 GMT</pubDate></item><item><title>bbum - 2013-01-25 22:05:46</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@bob Fair enough and I agree;  retainCount is very precise, but the value is, in practice, useless exactly because it lacks context.
&lt;br /&gt;
&lt;br /&gt;And by the time you get the context -- the full history of retain/release/autorelease events, their thread, and their backtrace -- the value of the absolute retain count becomes redundant.</description><guid isPermaLink="true">d27d7df6bbbfc3eba0466034e536ac9a</guid><pubDate>Fri, 25 Jan 2013 22:05:46 GMT</pubDate></item><item><title>bob - 2013-01-25 21:24:14</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@bbum: I didn't say that the value returned by retainCount was stable -- only that it reflects the number of retains and releases at that point (which may be inaccurate by the time it returns to you; but was accurate at some point).
&lt;br /&gt;
&lt;br /&gt;The thing about autorelease is what confuses people about retainCount, but it does not affect what I said -- retainCount reflects the number of retains and releases, but autoreleases are not releases (they cause a release later), so if you retain and then autorelease, of course retainCount will be higher.
&lt;br /&gt;
&lt;br /&gt;What I am trying to say is that retainCount "makes sense" if you knew all the retains and releases that happened to the object. So the problem with using retainCount is not with retainCount per se, but with the fact that you don't know all the retains and releases that various functions do (also concurrency is another problem). But a lot of times people treat retainCount it as if it's some completely arbitrary thing, that does not match retains and releases; and that's false.</description><guid isPermaLink="true">cc30305f150f81557b4eda26e10c8969</guid><pubDate>Fri, 25 Jan 2013 21:24:14 GMT</pubDate></item><item><title>bbum - 2013-01-25 21:00:24</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>And, yes, the `rand()` thing was an admittedly snarky joke.   It isn't random (though it effectively was under GC, btw, as retainCount was short circuited to `return self;`).</description><guid isPermaLink="true">6aeb0ce70ad56c2dd00f1caca4e7ff9d</guid><pubDate>Fri, 25 Jan 2013 21:00:24 GMT</pubDate></item><item><title>bbum - 2013-01-25 20:59:09</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@bob If you are implementing your own base class and control all implementations below it, retainCount is accurate as long as you don't have any concurrency and treat autorelease as a transitional state.
&lt;br /&gt;
&lt;br /&gt;Beyond that, though, the value returned by retainCount is not useful exactly because it is both non-deterministic and, of course, the value may be completely "weird" due to implementation details of the system frameworks.
&lt;br /&gt;
&lt;br /&gt;Even in the example you sight, the value you claim to be precise is not so precise. Claiming that "it is equal to 1" is specious exactly because that value may change immediately upon retrieval due to thread execution (and may effectively be in a transitional state due to autorelease).
&lt;br /&gt;
&lt;br /&gt;In a concurrent environment, the only way to guarantee that retainCount's return value is stable and accurate is if you &lt;i&gt;also&lt;/i&gt; put a lock/unlock around it that prevents any changes to the value (which means no retain/release until unlock).
&lt;br /&gt;
&lt;br /&gt;@Colin Handling allocation errors across small allocations is a waste of time.   If a program can't allocate 16 bytes, it is exceedingly likely that some other unhandled allocation failure has already left the app in a non-deterministic state.   And, of course, most handlers would end up trying to allocate memory and failing.
&lt;br /&gt;
&lt;br /&gt;(Handling *very large allocation* failures is definitely worth expending some thought on 32 bit systems.  On 64 bit systems, the symptom will happily hand you back a many GB of address space only to let you page to death as you touch the allocation.)</description><guid isPermaLink="true">fc04adaec303dd7e854fb95a2d4c2a56</guid><pubDate>Fri, 25 Jan 2013 20:59:09 GMT</pubDate></item><item><title>bob - 2013-01-25 20:55:12</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@Michael Bishop: well, there's an article right for you: Let's Build objc_msgSend &lt;a href="http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-build-objc_msgsend.html"&gt;http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-build-objc_msgsend.html&lt;/a&gt;</description><guid isPermaLink="true">b9daf43dbee6149b6ac9df4cd56f1f77</guid><pubDate>Fri, 25 Jan 2013 20:55:12 GMT</pubDate></item><item><title>bob - 2013-01-25 20:11:26</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@bbum: I am tired of this FUD about retainCount. NSObject's implementation of retainCount is perfectly deterministic, and is equal to 1 + the number of retains - the number of releases on that object. (Subclasses of course might have overridden these methods to do other things.) Period.
&lt;br /&gt;
&lt;br /&gt;Yes, the number is *not useful* to the user. But that does not mean that it is random.</description><guid isPermaLink="true">e9e0056a45c7d560eb7026df695e4f62</guid><pubDate>Fri, 25 Jan 2013 20:11:26 GMT</pubDate></item><item><title>bob - 2013-01-25 19:59:13</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>@Iain Delaney: It is part of the Objective-C language. self and _cmd are implicit parameters to every method in Objective-C.</description><guid isPermaLink="true">bda6ce8c30cc5ebdd20e6fad5ec08168</guid><pubDate>Fri, 25 Jan 2013 19:59:13 GMT</pubDate></item><item><title>Michael Bishop - 2013-01-25 19:28:13</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>How would you implement &lt;code&gt;objc_msgSend&lt;/code&gt;?
&lt;br /&gt;</description><guid isPermaLink="true">5cc954489ff2aeb120c164b0b897166b</guid><pubDate>Fri, 25 Jan 2013 19:28:13 GMT</pubDate></item><item><title>Chris L - 2013-01-25 19:11:00</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>I don't see why you should try to "gracefully" handle a failed memory allocation. Probably nothing is going to work right by the time that happens.</description><guid isPermaLink="true">7b3bfe5880fd08dff0c1647a82a8d528</guid><pubDate>Fri, 25 Jan 2013 19:11:00 GMT</pubDate></item><item><title>Colin - 2013-01-25 18:06:12</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Thank you for this interesting post.
&lt;br /&gt;
&lt;br /&gt;A question regarding the alloc method: Couldn't calloc failure (due to an out of memory condition) be handled gracefully like this:
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ (id)alloc
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MAObject *obj = calloc(1, class_getInstanceSize(self));
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (obj)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;obj-&amp;gt;isa = self;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;obj-&amp;gt;retainCount = 1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return obj;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;
&lt;br /&gt;&lt;/code&gt;
&lt;br /&gt;Or would it blow up anyway when returning NULL from alloc?</description><guid isPermaLink="true">dae3fe884d36327c7b025f105c4ff161</guid><pubDate>Fri, 25 Jan 2013 18:06:12 GMT</pubDate></item><item><title>bbum - 2013-01-25 17:56:02</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Your `retainCount` method is buggy.  It should be:
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- (NSUInteger)retainCount
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return rand();
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;
&lt;br /&gt;;-)
&lt;br /&gt;</description><guid isPermaLink="true">79211c498f161ee7f5ab6a9fc616e8df</guid><pubDate>Fri, 25 Jan 2013 17:56:02 GMT</pubDate></item><item><title>Iain Delaney - 2013-01-25 16:37:53</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2013-01-25-lets-build-nsobject.html#comments</link><description>Don't you actually need to define 'self' somewhere? I'm a little fuzzy on this, but isn't 'self' part of NSObject, rather than being part of the Objective-C language?</description><guid isPermaLink="true">d3139200827ecd773692135f438c8125</guid><pubDate>Fri, 25 Jan 2013 16:37:53 GMT</pubDate></item></channel></rss>
