<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>mikeash.com pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html comments</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>mikeash.com Recent Comments</description><lastBuildDate>Sat, 06 Jun 2026 20:15:38 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>mikeash - 2014-05-24 02:58:09</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Without looking at the code in detail (sorry), you should be safe as long as you call &lt;code&gt;objc_destructInstance&lt;/code&gt;. Fortunately, this call has been made public since I wrote this article, and is now the officially supported way to destroy an object while managing the memory yourself. &lt;code&gt;objc_constructInstance&lt;/code&gt; is probably also a good idea to use. If using the two of those still runs into trouble, I'd encourage filing a bug. This is something the runtime guys do care about (I think my prodding helped get these calls made public, and it didn't strike me as their intent to break custom allocations in the first place when I talked to them) and I think they'll get it fixed if it's broken.</description><guid isPermaLink="true">802807e05a2b27d8aa8d2177ed2d334f</guid><pubDate>Sat, 24 May 2014 02:58:09 GMT</pubDate></item><item><title>mmarino - 2014-05-19 16:25:47</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>First of all, apologies for posting on a 3-year-old blog entry, but this seems to be the standard reference for custom object allocations in obj-c.
&lt;br /&gt;
&lt;br /&gt;This seems to not be possible with recent versions of obj-c.  In particular, the run-time keeps track of whether or not [NSObject release] has been called on an object.  See, e.g.:
&lt;br /&gt;
&lt;br /&gt;&lt;a href="http://www.opensource.apple.com/source/objc4/objc4-551.1/runtime/NSObject.mm"&gt;http://www.opensource.apple.com/source/objc4/objc4-551.1/runtime/NSObject.mm&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;and in particular 
&lt;br /&gt;
&lt;br /&gt;bool
&lt;br /&gt;_objc_rootReleaseWasZero(id obj)
&lt;br /&gt;
&lt;br /&gt;where the SpinTable keeps track of whether or not release has been called (it sets SIDE_TABLE_DEALLOCATING).  I have not tried to work around this, but certainly it's possible to call another function than release to send the object back to the cache.  </description><guid isPermaLink="true">5b932b8ab2e645e6b9401932ddb03ece</guid><pubDate>Mon, 19 May 2014 16:25:47 GMT</pubDate></item><item><title>yaniv - 2013-02-05 13:28:52</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Can someone please explain me what this syntax exactly means: 
&lt;br /&gt;&lt;code&gt; *(id *)cachedObj &lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;Thanks !</description><guid isPermaLink="true">88118c2e39d96f88b3f0dd03b6c6eec0</guid><pubDate>Tue, 05 Feb 2013 13:28:52 GMT</pubDate></item><item><title>mikeash - 2011-01-14 16:21:16</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Good point. You'll probably want to round the size up to the nearest multiple of &lt;code&gt;sizeof(void *)&lt;/code&gt; to be safe.</description><guid isPermaLink="true">863795f947704a0ee1dc9bec13cbe06a</guid><pubDate>Fri, 14 Jan 2011 16:21:16 GMT</pubDate></item><item><title>johne - 2011-01-14 12:17:01</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>There's a potential problem with &lt;code&gt; AllocateNewBlockAndCache&lt;/code&gt;, namely that you use the size returned by &lt;code&gt;class_getInstanceSize(class)&lt;/code&gt; to "slice" up the allocation.  To the best of my knowledge, the size returned by &lt;code&gt;class_getInstanceSize()&lt;/code&gt; is not rounded up to the ABI required minimum boundary for correct alignment.
&lt;br /&gt;
&lt;br /&gt;The allocation returned by &lt;code&gt;malloc()&lt;/code&gt; is required to return an allocation that is guaranteed to be correctly aligned for any type.  Correct alignment is (probably) not guaranteed as it is currently written.  Whether or not this is a problem depends on the architecture.  It will probably work on x86, but not on RISCy CPUs.</description><guid isPermaLink="true">620844481e005f07fe270a8d5a130d5b</guid><pubDate>Fri, 14 Jan 2011 12:17:01 GMT</pubDate></item><item><title>Nathan de Vries - 2011-01-14 03:05:04</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Just found this tidbit in the Memory Usage Performance Guidelines [1]:
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogcommentquote"&gt;&lt;div class="blogcommentquoteinner"&gt;The calloc function reserves the required virtual address space for the memory but waits until the memory is actually used before initializing it. This approach is much more efficient than using memset, which forces the virtual memory system to map the corresponding pages into physical memory in order to zero-initialize them. Another advantage of using the calloc function is that it lets the system initialize pages as they’re used, as opposed to all at once.&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;I'd always assumed that using malloc + memset was functionally equivalent to using calloc. Not true, it seems!
&lt;br /&gt;
&lt;br /&gt;[1] &lt;a href="http://developer.apple.com/library/mac/#documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html"&gt;http://developer.apple.com/library/mac/#documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html&lt;/a&gt;</description><guid isPermaLink="true">568fffb8998f9e15bc4e498fb64cb236</guid><pubDate>Fri, 14 Jan 2011 03:05:04 GMT</pubDate></item><item><title>mikeash - 2011-01-13 16:54:09</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>As far as I know, yes, malloc does optimistic allocation. It will only ever return NULL if you're out of address space.
&lt;br /&gt;
&lt;br /&gt;As for calloc, I never pay attention to the arguments, and just leave one as 1. The fact that the zeroing and non-zeroing allocation calls take different size arguments has never made any sense to me....</description><guid isPermaLink="true">6f3b9bf689eaf4ddec5473dd6dc1dce4</guid><pubDate>Thu, 13 Jan 2011 16:54:09 GMT</pubDate></item><item><title>Nathan de Vries - 2011-01-13 06:36:51</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Very useful article — thanks Mike. Out of interest, do you know whether malloc uses an optimistic memory allocation strategy?
&lt;br /&gt;
&lt;br /&gt;Also, while it doesn't make a difference, calloc's API is:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;void * calloc(size_t count, size_t size);&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;You've flipped the arguments:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;id obj = calloc(class_getInstanceSize(self), 1);&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;It should read:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;id obj = calloc(1, class_getInstanceSize(self));&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;Cheers,
&lt;br /&gt;
&lt;br /&gt;Nathan de Vries</description><guid isPermaLink="true">7aea856a05c9d485ffb684f86137567e</guid><pubDate>Thu, 13 Jan 2011 06:36:51 GMT</pubDate></item><item><title>johne - 2011-01-11 19:35:06</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>You can make this thread safe with &lt;code&gt;OSAtomicEnqueue()&lt;/code&gt; and &lt;code&gt;OSAtomicDequeue()&lt;/code&gt;.  Basically,
&lt;br /&gt;
&lt;br /&gt;replace
&lt;br /&gt;&lt;code&gt; static id gCacheListHead;&lt;/code&gt;
&lt;br /&gt;with
&lt;br /&gt;&lt;code&gt;static OSQueueHead gCacheListHead = OS_ATOMIC_QUEUE_INIT;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;then replace
&lt;br /&gt;&lt;code&gt;static id GetObjectFromCache(void) { }&lt;/code&gt;
&lt;br /&gt;with
&lt;br /&gt;&lt;code&gt;static id GetObjectFromCache(void) { return(OSAtomicDequeue(&amp;amp;gCacheListHead, offsetof(id, isa))); }&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;and finally replace
&lt;br /&gt;&lt;code&gt;static void AddObjectToCache(id obj) { }&lt;/code&gt;
&lt;br /&gt;with
&lt;br /&gt;&lt;code&gt;static void AddObjectToCache(id obj) { OSAtomicEnqueue(&amp;amp;gCacheListHead, obj, offsetof(id, isa)); }&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;Completely untested, but that's the general idea.  This will provide a thread-safe atomic LIFO queue, even when multiple CPU's are concurrently adding and removing items.</description><guid isPermaLink="true">7661f2ded1362050b508fec134be454d</guid><pubDate>Tue, 11 Jan 2011 19:35:06 GMT</pubDate></item><item><title>Camille - 2010-12-19 01:15:06</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Very nice article, thanks Mike!</description><guid isPermaLink="true">bc64d1fbd29d69b75633ee5b8d26b13e</guid><pubDate>Sun, 19 Dec 2010 01:15:06 GMT</pubDate></item><item><title>iamleeg - 2010-12-18 16:58:16</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Another reason you might want to build a custom allocator: working with crypto code and you want to zero out the memory used in -dealloc. It can get easier just to define a new allocator and grab your 'sensitive' memory in any API from it.</description><guid isPermaLink="true">6dec4bcb6109cf274786265904edd215</guid><pubDate>Sat, 18 Dec 2010 16:58:16 GMT</pubDate></item><item><title>mikeash - 2010-12-17 22:17:22</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Nah, that's handled in &lt;code&gt;+allocWithZone:&lt;/code&gt;. It could go either place, but putting it there makes it easier to deal with (same-sized) subclasses.</description><guid isPermaLink="true">eb7056fd193251d8bac9f179a89048bb</guid><pubDate>Fri, 17 Dec 2010 22:17:22 GMT</pubDate></item><item><title>Seth Willits - 2010-12-17 21:53:37</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Err, make that if (obj) *(Class *)obj = [MyObject class];</description><guid isPermaLink="true">a3b5ac0694e9821922bd804aaf0b116e</guid><pubDate>Fri, 17 Dec 2010 21:53:37 GMT</pubDate></item><item><title>Seth Willits - 2010-12-17 21:49:34</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>GetObjectFromCache also needs to reset the isa pointer.
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*(Class *)obj = [MyObject class];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return obj;
&lt;br /&gt;&lt;/code&gt;</description><guid isPermaLink="true">5a4594d507f5b3a7d9256e399957ad7f</guid><pubDate>Fri, 17 Dec 2010 21:49:34 GMT</pubDate></item><item><title>mikeash - 2010-12-17 21:44:33</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>Thanks for that, fixed now.</description><guid isPermaLink="true">d585e6372ead2982ea60472f78c2c382</guid><pubDate>Fri, 17 Dec 2010 21:44:33 GMT</pubDate></item><item><title>Seth Willits - 2010-12-17 21:01:30</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-12-17-custom-object-allocators-in-objective-c.html#comments</link><description>GetObjectFromCache and AddObjectToCache are declared to return id, but don't.</description><guid isPermaLink="true">daf9f51b612f21cc8d45d1d7d8aaf325</guid><pubDate>Fri, 17 Dec 2010 21:01:30 GMT</pubDate></item></channel></rss>
