<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>bbum&#039;s weblog-o-mat &#187; Xcode</title>
	<atom:link href="http://www.friday.com/bbum/category/science/technology/apple/mac-os-x/xcode/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.friday.com/bbum</link>
	<description>...so google can index my head.</description>
	<lastBuildDate>Sat, 04 Feb 2012 06:32:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>retainCount is useless.</title>
		<link>http://www.friday.com/bbum/2011/12/18/retaincount-is-useless/</link>
		<comments>http://www.friday.com/bbum/2011/12/18/retaincount-is-useless/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 00:20:23 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=2038</guid>
		<description><![CDATA[The retainCount method just isn&#8217;t very useful as has been indicated in the answers to about a zillion StackOverflow questions. The documentation has this to say: Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references [...]]]></description>
			<content:encoded><![CDATA[<p>The <code>retainCount</code> method just isn&#8217;t very useful as has been indicated in the answers to about a <a href="http://stackoverflow.com/search?tab=newest&#038;q=%22retaincount%22">zillion StackOverflow questions</a>.</p>
<p>The <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html%23//apple_ref/occ/intfm/NSObject/retainCount">documentation has this to say</a>:</p>
<blockquote><p><strong>Important</strong>: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.</p></blockquote>
<p>Makes it pretty clear that you shouldn&#8217;t be calling <code>retainCount</code>, but it really doesn&#8217;t illuminate exactly how useless the method is outside of a very narrow context.</p>
<p>So, let us count the ways:</p>
<ol>
<li>The absolute retain count of an object may change at any time once an object has been passed through any system API.</li>
<li>Any subclass of any system provided class counts as &#8220;through system API&#8221;;  the retain count may be impacted by implementation details.</li>
<li>The retain count never reflects whether an object is autoreleased.</li>
<li>Autorelease is a per-thread concept whereas retain counts are global; race condition derived hilarity can easily ensue.</li>
<li>The <code>retainCount</code> method can never return 0.</li>
<li>Some classes are implemented as singletons some of the time.</li>
<li>Some classes may internally manipulate their retain count directly (I.e. no swizzle for you!).</li>
<li>While <code>retain/release</code> are effectively thread safe, there is always a race between calling <code>retainCount</code> and having the actual retain count change in some other execution context.</li>
</ol>
<p>Bottom line:  the only time the absolute <code>retainCount</code> can be conclusively used for analytic purposes is if you have the backtrace of every retain and release that contributed to the current retain count&#8217;s value (there is another use case, documented at the end).   If you have <em>that</em>, then you don&#8217;t need the retain count and, fortunately, Instruments is already generally quite adept at producing a per-object inventory of retains and releases for you (see <em><a href="http://developer.apple.com/library/IOs/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/ViewingandAnalyzingData/ViewingandAnalyzingData.html#//apple_ref/doc/uid/TP40004652-CH5-SW23">Analyzing Data with the Allocations Instrument</a></em>&#8220;.</p>
<p>In general, <strong>you should consider the retain count as a delta</strong>.   Your code causes the retain count to <em>increase and decrease</em>.   You don&#8217;t <code>+alloc</code> an object with a retain count of 1.  Instead, you <code>+alloc</code> an object with a retain count of +1.  If you want that object to go away, you need to do something &#8212; <code>release</code>, always and eventually &#8212; that causes the retain count to be decremented by 1.</p>
<p>It really is that simple.  </p>
<p>Almost.</p>
<p>Concurrency &#8212; whether through threading or GCD &#8212; throws a bit of a wrench in the works (as it always does).   Namely, the retain count should really be considered as a per concurrency context delta.  If thread or queue <code>A</code> wants to do something with object <code>X</code>, it should hold a +1 <code>retainCount</code> on <code>X</code> for the duration of said operation.   One subtle detail that will bear repeating later;   an <code>autorelease</code>&#8216;d object <em>does not contribute to thread safety</em>.  That is, if thread or queue <code>A</code> wants to pass <code>X</code> to thread or queue <code>B</code>, there must be an explicit <code>retain</code> in <code>A</code> that is balanced by a release (or synchronization event back to <code>A</code>) in <code>B</code>.</p>
<p>Now, some of the enumerated claims may either seem specious at best or, certainly, not obvious as to exactly how it undermines the validity of the retain count.<span id="more-2038"></span>
<ol>
<li><strong>The absolute retain count of an object may change at any time once an object has been passed through any system API.</strong></li>
<p>The system is free to <code>retain</code> and <code>release</code> any object at whim and, in fact, it will often do so.  An object may be shoved into a collection, it might be cached into a map somewhere by a computed key, or it might be <code>retain</code>&#8216;d long enough to survive enqueueing for execution asynchronously.</p>
<p>As well, the object may be retain&#8217;d then autorelease&#8217;d such that the retainCount will look like it is N when it is really, effectively, N-1.   If that retain/autorelease happened in a queue somewhere, the number returned may imply a greater # of strong references than truly exist.</p>
<li><strong>Any subclass of any system provided class counts as &#8220;through system API&#8221;;  the retain count may be impacted by implementation details.</strong></li>
<p>This is really the same point as the first, but emphasizes that all bets truly are off once you subclass a system class.   As the system&#8217;s use of concurrency during drawing grows over time, you can expect that any UI related subclassed classes will likely have their retain counts manipulated across concurrency boundaries potentially frequently.</p>
<li><strong>The retain count never reflects whether an object is autoreleased.</strong></li>
<p>When you call <code>autorelease</code>, not much really happens.  The object is neither <code>retain</code>&#8216;d nor <code>release</code>&#8216;s.  Instead, it is added to the current per-thread autorelease pool.   The <code>release</code> is effectively delayed until the pool is drained or deferred to the next outermost pool if the pool is popped without draining (which can happen due to bugs or exceptions [exceptions are an indication of bugs in and of themselves in Cocoa]).</p>
<p>Once an object is added to an <code>autorelease</code> pool, there is no way to query whether or not it is in such a state.   Thus, whatever retain count is currently returned may not actually reflect the effective retain found at all.</p>
<li><strong>Autorelease is a per-thread concept whereas retain counts are global; race condition derived hilarity can easily ensue.</strong></li>
<p>But it gets worse (at least, worse for the developer making the mistake of thinking <code>retainCount</code> is meaningful).</p>
<p>The retain count of an object is actually global to all contexts of concurrency.  An object has one and only one retain count.   While calling <code>retain</code> and <code>release</code> are concurrency safe, there is no way to express <em>call <code>retain</code> and don&#8217;t let another execution context increment or decrement it until I&#8217;m done pondering the return value.</em></p>
<li><strong>The <code>retainCount</code> method can never return 0.</strong></li>
<p>When an object&#8217;s retain count transitions from 1 to 0, the object is deallocated (usually).  As a result, if you <code>retainCount</code> on a non-nil reference, it can never return zero because doing so would require calling a method on a deallocated object which is undefined behavior.</p>
<p>Or, to put it more bluntly, this can never work (Yes, I had to go there):</p>
<pre>while([bg retainCount]!=0)
{
  [bg release];
}
</pre>
<p>One might claim that if you message nil, you&#8217;ll get 0 in return.  True;  but <em>no code outside of a short circuit in <a href="http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/">objc_msgSend()</a> is executed.</em>   That is, the method isn&#8217;t returning zero, the messaging mechanism is short circuiting prior to calling the method.</p>
<li><strong>Some classes are implemented as singletons some of the time.</strong></li>
<p>Consider:</p>
<pre>
NSNumber *n = [NSNumber numberWithInt: 4];
printf("%p rc: %u\n", n, [n retainCount]);
n = [NSNumber numberWithInt: 4];
printf("%p rc: %u\n", n, [n retainCount]);
n = [NSNumber numberWithInt: 42];
printf("%p rc: %u\n", n, [n retainCount]);
n = [NSNumber numberWithInt: 42];
printf("%p rc: %u\n", n, [n retainCount]);
</pre>
<p>And the output on i386:</p>
<pre>0x115410 rc: 2
0x115410 rc: 3
0x115950 rc: 1
0x115df0 rc: 1
</pre>
<p>Now consider x86_64:</p>
<pre>0x483 rc: 9223372036854775807
0x483 rc: 9223372036854775807
0x2a83 rc: 9223372036854775807
0x2a83 rc: 9223372036854775807
</pre>
<p>For this particular class, the behavior is different depending on value <em>and</em> depending on architecture.  You could expect potentially even different behavior on an iOS device.   Likewise, if you were to run the 64 bit variant on Snow Leopard, it would be different yet again!</p>
<p>Internally, NSNumber uses singletons for a small subset of values on certain platforms.  On x86_64, it uses tagged pointers (<a href="http://objectivistc.tumblr.com/post/7872364181/tagged-pointers-and-fast-pathed-cfnumber-integers-in">Bavarious explains tagged pointers quite well in this blog post</a>.  I should update the objc_msgSend() tour to reflect the new messenger in Lion, too) to avoid allocating anything for the object altogether.</p>
<p>In all cases, relying upon the retain count of an NSNumber will create a dependency on system behavior that will quite likely change in the future, breaking your program rather badly.</p>
<p>Many other classes within the frameworks have similar optimizations for the common cases.  Likewise, because of polymorphism and/or duck typing, it is likely that a system API declared to return an instance of, say, <code>NSString</code> might return an instance of a seemingly unrelated class whose interface is string compatible.</p>
<li><strong>Some classes may internally manipulate their retain count directly (I.e. no swizzle for you!).</strong></li>
<p>It may be tempting to override <code>retain</code>, <code>release</code> and <code>autorelease</code> in existing classes using a swizzling mechanism or the like.   Depending on the class, you might find that the retain count of an object is changing more than the # of calls to retain/release/autorelease might otherwise warrant!</p>
<p>This is because a class might choose to implement a retain count mechanism differently than the one provided by <code>NSObject</code> and, thus, might internally directly manipulate the retain count without going through the various methods.</p>
<p>Since the retainCount of an object is not an observable property (ewww… boy howdy that&#8217;d be ugly if it was), this direct manipulation is perfectly valid.  However, it means that you cannot count on being able to externally modify an existing class to observe the retain count.</p>
<p>Nor should you need to.   The system classes are designed such that they <em>should be</em> compatible with the Allocation Instrument&#8217;s ability to track reference count changing events, including grabbing a backtrace.   If you find a class that isn&#8217;t, file a bug, please.</p>
<li><strong>While <code>retain/release</code> are effectively thread safe, there is always a race between calling <code>retainCount</code> and having the actual retain count change in some other execution context.</strong></li>
<p>Mmm… concurrency… where <code>1+1</code> can yield <code>3</code>.</p>
<p>As was mentioned before, there is no operation via which you can query an object for its <code>retainCount</code> in a fashion that guarantees the retain count won&#8217;t change immediately after you retrieve the value, including potentially deallocating the object.</p>
<p>That is to say, there is no <code>retain/release</code> locking mechanism.  </p>
<p>Thus, as soon as you retrieve the <code>retainCount</code> of an object, that value may be incorrect unless you can absolutely guarantee that the object is not being manipulated by any other execution context.   And the only way to guarantee that is to pretty much stick to a direct subclass of NSObject (which, in and of itself, isn&#8217;t really technically correct either) and limiting manipulation of said object(s) only to threads/queues where you exactly control every aspect of interaction with said object;  i.e. no system APIs for you!
</ol>
<p>The above doesn&#8217;t even consider the inherent design fragility in colluding the reference count of objects with other functionality.  The classic &#8220;scarce resource recollection&#8221; problem of GC very much exists in a manual retain-release realm, for example.</p>
<hr />
<p>So, when <em>is</em> <code>retainCount</code> useful?</p>
<p>I have encountered a handful of cases where the retain count of an object was used internally as a sort of &#8220;mode of use&#8221; indicator.  That is, if an object&#8217;s retainCount is 2 when <code>-release</code> is invoked, the framework will assume, say, that the object is transitioning from &#8220;in use&#8221; to &#8220;available for quick reuse&#8221;.  Typically, this is a sort of allocation cache or instance cache.   Often, this is done because instantiation of the object is fairly expensive and, thus, the goal is to create a pool of available objects that can quickly be reused.</p>
<p>While a valid use, it tends to be fragile and tends to make crashes more difficult to analyze.  Namely, one stray <code>release</code> or <code>autorelease</code> and you are likely to have a crash in the caching mechanism.  At least with a crash in in <code>NSAutoreleasePool</code>, it is immediately obvious where things went off the rails.</p>
<p>A far less fragile solution is to encapsulate the expensive bits within a second container within the object.  That container can be &#8220;checked in&#8221; and &#8220;checked out&#8221; by the object as a normal part of allocation/deallocation.   This decouples cache magic from retain count.</p>
<hr />
<p>The best possible solution to all of this is to <em>move to ARC!</em>  <a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html">Automatic Reference Counting</a>, by and large, works incredibly well for a technology that is so new.  The compiler and runtime teams have taken a very conservative approach that makes this so.  Basically, if the compiler can&#8217;t reason through a piece of code to determine with total certainty exactly what the retain/release behavior should be, it generates an error instead.</p>
<p>It works quite well and many of Apple&#8217;s newer releases feature big chunks of code that are ARC&#8217;d.</p>
<p>If you can&#8217;t go ARC yet for whatever reasons, then dealing with manual retain-release is really quite simple and <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html">covered well in the documentation</a>.  The key is to ignore the retain count as a value and treat it purely as something you increase and decrease;  you must balance every increase with a decrease if you want a particular object to be deallocated or over-released in the case of too many decrements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2011/12/18/retaincount-is-useless/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>When is a Leak not a Leak? Using Heapshot Analysis to Find Undesirable Memory Growth</title>
		<link>http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/</link>
		<comments>http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 20:20:31 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=1949</guid>
		<description><![CDATA[The other day, I was in need of a Cocoa application that launches quickly that has a standard document model. At random, I chose the rather awesome Hex Fiend. As I often do, I also had top -u -o pid running in a Terminal window. And I noticed something odd. As expected, the RPRVT of [...]]]></description>
			<content:encoded><![CDATA[<p>The other day, I was in need of a Cocoa application that launches quickly that has a standard document model.  At random, I chose the rather awesome <a href="http://ridiculousfish.com/hexfiend/">Hex Fiend</a>.  As I often do, I also had <code>top -u -o pid</code> running in a Terminal window.</p>
<p>And I noticed something odd.  As expected, the RPRVT of <i>Hex Fiend</i> was growing on each <i>cmd-n</i>.  However, <em><strong>the RPRVT was not decreasing the same amount every time I hit cmd-w</strong></em>.</p>
<p>That ain&#8217;t right.   Or it might be.  Beyond evidence that a memory use problem may exist, <code>top</code> is a horrible tool for determining if a problem is real or what the actual problem might be.</p>
<p>In this case, the issue looks like a simple memory leak.  <code>Hex Fiend</code> is allocating and retaining some set of objects, but not releasing them.  The easiest first step is to use the <code>leaks</code> command line tool:</p>
<pre>% leaks "Hex Fiend"
leaks Report Version:  2.0
Process:         Hex Fiend [3435]
Path:            /Volumes/Data/Applications/Hex Fiend.app/Contents/MacOS/Hex Fiend
Load Address:    0x100000000
Identifier:      com.ridiculousfish.HexFiend
Version:         2.0.0 (200)
Code Type:       X86-64 (Native)
Parent Process:  launchd [122]
Date/Time:       2010-10-16 20:47:09.935 -0700
OS Version:      Mac OS X 10.6.4
Report Version:  7
Process 3435: 22980 nodes malloced for 2600 KB
Process 3435: 0 leaks for 0 total leaked bytes.
</pre>
<p>OK; whatever the problem is, it isn&#8217;t &#8220;leaked&#8221; memory in the traditional definition of &#8220;leaked memory&#8221;.</p>
<p>That is, whatever memory is being allocated and never released is still being referenced somewhere.  Maybe a circular retain.  Maybe something that has a weak reference from the rest of the App&#8217;s object graph such that leaks can&#8217;t detect.</p>
<p>In other words, this isn&#8217;t just a simple memory leak and it will require more advanced tools to fix.</p>
<p><span id="more-1949"></span>Fortunately, the <em><a href="http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Introduction/Introduction.html%23//apple_ref/doc/uid/TP40004652-CH1-SW1">Allocations Instrument</a></em> provides exactly the tool we need.  It is called <strong>Heapshot Analysis</strong> and it is brutally effective at deducing these kinds of problems.</p>
<p>To use:</p>
<ul>
<li>Launch Instruments and select the <strong>Allocations</strong> template under the <strong>Memory</strong> category.</li>
<li>Target the application you want to analyze.  It can already be running or you can launch it from Instruments.  As well, you can launch it from Xcode via the <strong>Run With Performance Tools</strong> menu.</li>
<li>(10) Do something in the application where you return to the starting state.  For <i>Hex Fiend</i>, this particular case is as simple as creating a new document and then closing it.   For an optimal application, this activity should effectively cause no memory growth (or very little).</li>
<li>In the Allocations Instrument, press the <b>Mark Heap</b> button</li>
<li>Goto 10 (and repeat 5 or 6 times).</li>
</ul>
<div class="imgLeft"><img src="http://www.friday.com/bbum/wp-content/uploads/2010/10/Step-1.png" alt="Step 1.png" title="Step 1.png" border="0" width="600" height="233" /></div>
<p>I ended up with the data as seen to the left.   Each &#8220;Heapshot&#8221; iteration represents opening, then closing, an untitled window with no data in it.</p>
<p>The &#8220;Heap Growth&#8221; and &#8220;Still Alive&#8221; columns provide a summation of all of the objects <strong><em>in that heapshot that still exist in all subsequent samplings of the heap</em></strong>.  That is, in <em>Heapshot 3</em>, there were 36.08K of allocations spread across 260 allocation events that continued to exist throughout the rest of the run.</p>
<p>Specifically:  the values in those columns represent <strong>permanent heap growth</strong>.</p>
<p>When creating, then closing, an untitled document there should be, ideally, no heap growth.  That there is ~35K per document of permanent heap growth indicates that a leak does exist (regardless of what leaks said above).</p>
<p>Note that as you continue to iterate, you might see the values of previous <em>Heapshot</em> samples decrease.   That is because objects allocated in that sample &#8212; at that heap mark &#8212; have been released.  That is, <em>every single object listed in that table &#8212; all ~25,000 or so in that screenshot alone &#8212; are very much in memory, using resources, and sticking around.</em><br />
<br clear="left"/></p>
<p>Instruments lets us dive deeper.</p>
<div class="imgLeft"><img src="http://www.friday.com/bbum/wp-content/uploads/2010/10/Step-2.png" alt="Step 2.png" title="Step 2.png" border="0" width="600" height="236" />
</div>
<p>Not only can we expand any given <em>Heapshot</em> iteration to see the inventory of permanent objects allocated in that iteration, but we can dive all the way down to the individual allocations and see a backtrace of exactly where it was allocated.</p>
<p>Looking at many  of the allocations, they all seem to be during either the initialize of an instance of <code>MyDocument</code> or during loading of the user interface related with the same.</p>
<p>No surprises there;  the inventory of objects is clearly related to the document.</p>
<p>What <em>is</em> surprising, though, is that an instance of <code>MyDocument</code> doesn&#8217;t show up on that list!   It looks like the instance of <code>MyDocument</code> is correctly being deallocated on window close, <em>but much of the user interface related to the document is <strong>not</strong></em>!<br />
<br clear="left"/></p>
<p>While we clearly have enough evidence to suspect <code>MyDocument</code> as being the source of the issue, we can confirm this further within Instruments.</p>
<p>Turn on <em>Record reference counts</em> in the Allocations instrument.  When the app isn&#8217;t running, hit the little (i) in the Allocations track in Instruments and click the check box. Then run the application and do the same set of samples (or turn this on from the beginning if you didn&#8217;t forget like I did).</p>
<p>Now, when you click through any allocation, you&#8217;ll see a list of events that includes the point of allocation and all subsequent retain/release events.   Clicking through many of the random objects in any given <em>Heapshot</em> sample shows two things.  First, all of the objects ended with a retain count of 1 &#8212; not 2, not 5, but 1 &#8212; this indicates that whatever the problem is, it is likely pretty consistent and we can fix it once and be done with it.  Secondly, the non-UI related objects like <em>DataInspector</em> or <em>NSBigMutableString</em> have very few events and they largely come from <code>[MyDocument -init]</code>, further confirming our suspicions.</p>
<p>Now it is time to turn to the source.</p>
<p>Which I need to download;  all of the above was done against the app without the source.</p>
<p>OK &#8212; got it &#8212; now &#8212; start with <code>MyDocument</code>&#8216;s <code>init</code> method (which doesn&#8217;t do the <code>self = [super init]; if (self) {...} return self;</code> dance.  Boo.) and compare it to <code>dealloc</code></p>
<p>The <code>init</code> method looks fairly straightforward;  allocate a bunch of stuff, glue it together, return self:</p>
<pre>
- init {
    [super init];
    lineCountingRepresenter = [[HFLineCountingRepresenter alloc] init];
    hexRepresenter = [[HFHexTextRepresenter alloc] init];
    asciiRepresenter = [[HFStringEncodingTextRepresenter alloc] init];
    scrollRepresenter = [[HFVerticalScrollerRepresenter alloc] init];
    layoutRepresenter = [[HFLayoutRepresenter alloc] init];
    statusBarRepresenter = [[HFStatusBarRepresenter alloc] init];
    dataInspectorRepresenter = [[DataInspectorRepresenter alloc] init];
    ... etc ...
</pre>
<p>As a matter of fact, pretty much all of those representers are showing up as still in memory per each Heapshot mark!</p>
<p>And, diving into the individual retain/releases, we see that some of the representers are connected to other representers.   So, if anyone of those representers is sticking around, it might likely keep others alive with it, too!  Or it could be a circular retain issue.  But, before we start trying to deduce hard problems, we should exhaust the simple causes first and look at the <code>dealloc</code> method.</p>
<p>The first thing that jumps out at me is that the <code>dealloc</code> method is trying to do something clever.  Instead of line-by-line calling <code>release</code> on every object allocated in <code>init</code>, it does:</p>
<pre>
    [[self representers] makeObjectsPerformSelector:@selector(release)];
</pre>
<p>OK.  So, what does <code>representers</code> look like?</p>
<pre>
- (NSArray *)representers {
    return [NSArray arrayWithObjects:lineCountingRepresenter, hexRepresenter,
               asciiRepresenter, scrollRepresenter,
               dataInspectorRepresenter, statusBarRepresenter, nil];
}
</pre>
<p><strong>Waitaminute there</strong>&#8230;. comparing that array&#8217;s contents to the items allocated in <code>init</code>, we see that the <em><code>layoutRepresenter</code> is missing</em>.  Nor is it explicitly released anywhere else in <code>dealloc</code>!</p>
<p>That&#8217;d be the leak right there!   And <strong>leaks</strong> won&#8217;t detect it because there are enough non-retained relationships that the objects look like they are still reachable from the application&#8217;s core object graph!</p>
<p>The naive fix would be to add <code>layoutRepresenter</code> to the array returned by <code>-representers</code>.   However, the <code>layoutRepresenter</code> seems to be kinda special in its role and, frankly, I really hate tricky <code>dealloc</code> games like making an array of objects perform <code>release</code>.</p>
<p>So, I replaced the <code>performSelector:</code> in <code>dealloc</code> with:</p>
<pre>
    [lineCountingRepresenter release];
    [hexRepresenter release];
    [asciiRepresenter release];
    [scrollRepresenter release];
    [layoutRepresenter release];
    [statusBarRepresenter release];
    [dataInspectorRepresenter release];
</pre>
<div class="imgLeft"><img src="http://www.friday.com/bbum/wp-content/uploads/2010/10/Step-3.png" alt="Step 3.png" title="Step 3.png" border="0" width="600" height="274" />
</div>
<p>Running the heapshot analysis again shows that the # of permanent allocations per iteration has dropped from ~250 to a consistent 8.   Vast improvement, but still not perfect.</p>
<p>Looking at the remaining allocations, <em>every single one is allocated in <code> drawLineNumbersWithClipStringDrawing</code>.</em><br />
<br clear="left"/></p>
<p>In particular, it is the drawing call here that is the source of the remaining leaks (except one):</p>
<pre>
	    NSString *string = [[NSString alloc] initWithBytesNoCopy:buff
						length:newStringLength
						encoding:NSASCIIStringEncoding freeWhenDone:NO];
            [string drawInRect:textRect withAttributes:textAttributes];
            [string release];
</pre>
<p>But, wait, how can that be?  Well, it could be a bug in the AppKit.  Or it could be some kind of a weird cache.   As a matter of fact, if you create about 30 documents in <em>Hex Fiend</em>, then close them all, you will see the previous heap marks drop to <em>7 objects remaining</em>.  So, clearly, there is some kind of a size limited cache that is eventually being pruned.  Obviously, not a very efficient cache if it is filling with copies of the same objects.  I like to call these kinds of caches <strong><em>write only caches</em></strong>.  All the benefits of high memory use combined with all the efficiencies of a 100% cache miss rate! FTW!</p>
<p>The one other leak, though, is that the <code>dealloc</code> method in <code>HFLineCountingView</code> is not releasing the <code>textContainer</code>.   First, I&#8217;ll fix that and re-measure.   Done.  That removes one object from each Heapshot iteration.</p>
<p>OK &#8212; so, looking at the remaining objects, we have a set of objects that look an awful lot like a set of attributes for text;  a paragraph style, color, etc&#8230;</p>
<p>Sure enough, <code>textAttributes</code> is not being <code>release</code>d in <code>dealloc</code>.</p>
<div class="imgLeft"><img src="http://www.friday.com/bbum/wp-content/uploads/2010/10/Step-4.png" alt="Step 4.png" title="Step 4.png" border="0" width="428" height="143" /></div>
<p>So, where do we stand?</p>
<p>See for yourself!</p>
<p>Not bad!  No leaks on many iterations.  That 1 4KB malloc seen in <em>some</em> iterations is likely some internal cache in the AppKit.  That it doesn&#8217;t always appear and eventually goes away indicates that it is both behaving correctly and can be ignored.</p>
<p>The next step would be to do the same kind of testing, only with documents that contain actual data.  Then do the testing after making a set of edits and undoing them.</p>
<hr />
<p><strong><em>Heapshot analysis</em></strong> has proven to be an incredibly effective tool for identifying and fixing memory use issues in applications.   The above style of use where you pick a task that should return state back to the same as it was when you started is the most effective form of this analysis.</p>
<p>However, this same approach can be used for applications that build up or change state over time (think Mail, which has new messages coming in all the time or an application with an accretion of logs or undo state).</p>
<p>Fire up your application under Instruments and periodically hit &#8220;Mark Heap&#8221; when your app is in a reasonable state.   The more Heap Shots you capture, the easier it is to analyze.   Look at any given iteration and ask yourself <em>Why do these objects created way back when still exist in memory and is their use of resources justified?</em>.   The follow up question is <em>What can I do to make the permanent memory accretion smaller?</em>.<br />
<br clear="left"/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>PyObjC Xcode Templates now in Subversion</title>
		<link>http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/</link>
		<comments>http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 07:51:31 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/</guid>
		<description><![CDATA[Ronald and I realized that the Xcode templates that are included in Leopard didn&#8217;t make it into the PyObjC repository. So, I moved &#8216;em over. You can find them in the PyObjC subversion repository. These aren&#8217;t just templates, though. See the README.txt. As it implies, the project-tool.py script is used to effectively convert between Xcode [...]]]></description>
			<content:encoded><![CDATA[<p>Ronald and I realized that the Xcode templates that are included in Leopard didn&#8217;t make it into the PyObjC repository.</p>
<p>So, I moved &#8216;em over.</p>
<p>You can find them in the <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2/pyobjc-xcode/">PyObjC subversion repository</a>.</p>
<p>These aren&#8217;t just templates, though.   See the <a href="http://svn.red-bean.com/pyobjc/branches/pyobjc2/pyobjc-xcode/Project%20Templates/README.txt">README.txt</a>.</p>
<p>As it implies, the project-tool.py script is used to effectively convert between Xcode templates and buildable projects.  That is, you can create a project that builds/runs like a regular Xcode project, and then easily turn it into a template with the invocation of a simple command line like this:</p>
<pre>
project-tool.py -k -v --template Cocoa-Python\ Document-based\ Application/CocoaDocApp.xcodeproj/TemplateInfo.plist \
    Cocoa-Python\ Document-based\ Application/ \
    ~/Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/AA\ Testing/Cocoa-Python\ Document-based\ Application
</pre>
<p>Or, specifically:</p>
<pre>./project-tool --help
Usage: project-tool.py [options] <source> <dest>

    Copies tree of templates or projects from <source> to <dest>.
    Before copying, it cleans up <source> by removing various bits of garbage.
    After copying, it transforms <dest> by replacing strings with their Xcode
    template counterparts.

    The reverse flag can be used to reverse this process; turning an Xcode
    template into a working project.

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         verbose
  -k, --kill-dest       erase </dest><dest> (no warning)
  -r, --reverse         reverse transformation (template -> editable project)
  -w, --working         try to make destination into a working project
  -n, --nib             rewrite NIB files to 10.5 text-only format
  -t TEMPLATEFILE, --template=TEMPLATEFILE
                        path to TemplateInfo.plist that should be used during
                        conversion
</dest></source></dest></source></dest></source></pre>
<p>Nothing remotely Python specific about it.   And, as some have noticed, the PyObjC Cocoa templates leverage the new Interface Builder file format (<a href="http://developer.apple.com/documentation/DeveloperTools/Conceptual/IB_UserGuide/BuildingaNibFile/chapter_4_section_6.html">xib</a>) such that all kinds of substitutions happen in the templated interfaces, too.   As in:  No more <em><strong>MyDocument</strong></em> ever again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2007/12/03/pyobjc-xcode-templates-now-in-subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode 2.3 is now available.</title>
		<link>http://www.friday.com/bbum/2006/05/23/xcode-23-is-now-available/</link>
		<comments>http://www.friday.com/bbum/2006/05/23/xcode-23-is-now-available/#comments</comments>
		<pubDate>Tue, 23 May 2006 18:36:08 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2006/05/23/xcode-23-is-now-available/</guid>
		<description><![CDATA[Xcode 2.3 is now available. Beyond fixing a boatload of bugs and numerous performance improvements, Xcode 2.3 adds DWARF as a native symbol format. DWARF yields a significantly higher fidelity debugging experience, especially for complex C++ code, while also reducing the memory requirements of the linker. Full release notes available on Apple&#8217;s developer tools web [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://developer.apple.com/tools/xcode/">Xcode 2.3</a> is now available.</p>
<p>Beyond fixing a boatload of bugs and numerous performance improvements, Xcode 2.3 adds DWARF as a native symbol format.  DWARF yields a significantly higher fidelity debugging experience, especially for complex C++ code, while also reducing the memory requirements of the linker.</p>
<p>Full release notes available <a href="http://developer.apple.com/releasenotes/DeveloperTools/Xcode/Xcode.html">on Apple&#8217;s developer tools web site.</a></p>
<p>Xcode 2.3 also includes a new distributed build subsystem called Dedicated Network Builds.   The preferences pane is a bit fragile &#8212; don&#8217;t poke at it too hard &#8212; but the underlying technology is some neat stuff.</p>
<p>While DistCC remains as the solution of choice for ad-hoc builds on small networks, Dedicated Network Builds [DNB] focuses on accelerating large projects where a farm of machines can be dedicated as builders.   In particular, DNB shines with large C++ projects.</p>
<p>Behind the scenes, DNB distributes compilation jobs from your local machine &#8212; the recruiter &#8212; to the builder machines &#8212; the volunteers &#8212; using a set of daemons to connect everything together.   On the recruiter, a daemon monitors the filesystem to ensure that changes made to the filesystem will cause the remote volunteer caches to be invalidated in an appropriately minimalist fashion.</p>
<p>The volunteers execute the jobs against a mirrored copy of the recruiter&#8217;s local filesystem, source, headers, compiler and all.   As such, the only dependency between your local machine and the builders is that they are both the same architecture (ppc or i386) and they are running very close to the same version of Mac OS X (i.e. 10.4.5 will be compatible with 10.4.6, but not 10.3.9).</p>
<p>A great deal of effort went into ensuring that cache management wouldn&#8217;t swamp the recruiter&#8217;s network connection.  There is still a hefty cache warmup hit, but the volunteers have the ability to resolve cache misses amongst themselves as well as resolving cache misses against their own local filesystem, when possible.</p>
<p>As one can imagine, there is considerably more to this technology than is described above.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2006/05/23/xcode-23-is-now-available/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Unit Testing and Code Coverage in Xcode</title>
		<link>http://www.friday.com/bbum/2005/10/29/unit-testing-and-code-coverage-in-xcode/</link>
		<comments>http://www.friday.com/bbum/2005/10/29/unit-testing-and-code-coverage-in-xcode/#comments</comments>
		<pubDate>Sat, 29 Oct 2005 18:10:33 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=539</guid>
		<description><![CDATA[Chris Hanson and I both intended to write something like this someday. Now we don&#8217;t have to. Go read this article about unit testing and code coverage. Specifically, Chris gives detailed instructions on how to integrate gcov based code coverage into Xcode while also leveraging Xcode&#8217;s support for unit testing. Excellent article. Thanks for writing [...]]]></description>
			<content:encoded><![CDATA[<p>Chris Hanson and I both intended to write something like this someday.  Now we don&#8217;t have to.</p>
<p>Go read <a href="http://www.supermegaultragroovy.com/Software%20Development/xcode_code_coverage_howto">this article</a> about unit testing and <i>code coverage</i>.   Specifically, Chris gives detailed instructions on how to integrate gcov based code coverage into Xcode while also leveraging Xcode&#8217;s support for unit testing.</p>
<p>Excellent article. Thanks for writing it, Chris.   I hope you don&#8217;t mind if I file a couple of bugs against Xcode to remind us to integrate something like what you have done sometime in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2005/10/29/unit-testing-and-code-coverage-in-xcode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Advanced Breakpoints</title>
		<link>http://www.friday.com/bbum/2005/10/12/advanced-breakpoints/</link>
		<comments>http://www.friday.com/bbum/2005/10/12/advanced-breakpoints/#comments</comments>
		<pubDate>Wed, 12 Oct 2005 16:00:58 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=534</guid>
		<description><![CDATA[Chris Hanson discusses Xcode&#8217;s advanced breakpoints today. One very important feature of the advanced breakpoints found within Xcode is the ability to cause something to happen in the debugger &#8212; play a sound, print some data, run some AppleScript or invoke a shell script &#8212; without interrupting the application being debugged beyond stopping it briefly [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.livejournal.com/users/chanson/123150.html">Chris Hanson discusses Xcode&#8217;s advanced breakpoints</a> today.</p>
<p>One very important feature of the advanced breakpoints found within Xcode is the ability to cause something to happen in the debugger &#8212; play a sound, print some data, run some AppleScript or invoke a shell script &#8212; <i>without interrupting the application being debugged</i> beyond stopping it briefly to take whatever action is specified in the breakpoint.</p>
<p>For debugging stuff like drag-n-drop, mouse tracking, and other human-computer-interaction related functionality, being able to break, take action, and continue the application without de-activating the application or otherwise messing with the context of event processing is absolutely critical.</p>
<p>In modern applications, the challenges of debugging are often not about which line of code is broken, but a matter of figuring out which of the 100,000 executions of a particular line of code is broken.   Worse, the line of code is generally going to be invoked along one of many paths, often further convoluted by the code&#8217;s presence within a class hierarchy such that invocation is determined by state or customization applied by subclasses.</p>
<p><i>printf style debugging</i> is often derided as an amateurish approach to figuring out what is going on.  And it does suck.  But it is often the only way to really figure out what is going on.</p>
<p>Until now.   I&#8217;m finding that I will configure a breakpoint to log-and-continue.  Once I figure out what offensive value is at the root of a problem, I can easily configure the breakpoint to no longer continue and to only stop when that value is present.</p>
<p>End result;  no more stop/print/continue by hand with the debugger constantly futzing with the event processing context of the application.</p>
<p>Very, very useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2005/10/12/advanced-breakpoints/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Job Openings on the Xcode Team</title>
		<link>http://www.friday.com/bbum/2005/07/21/job-openings-on-the-xcode-team/</link>
		<comments>http://www.friday.com/bbum/2005/07/21/job-openings-on-the-xcode-team/#comments</comments>
		<pubDate>Thu, 21 Jul 2005 07:46:24 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Jobs]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=483</guid>
		<description><![CDATA[We have a bunch of open positions within the Xcode team. If you or anyone you know is interested, has the skills, and wants to work at a truly awesome company (seriously &#8212; working at Apple is a blast), please send a resume/CV my way and apply for the job through the official channels which [...]]]></description>
			<content:encoded><![CDATA[<p>We have a bunch of open positions within the <a href="http://www.apple.com/macosx/features/xcode/">Xcode team</a>.   If you or anyone you know is interested, has the skills, and wants to work at a truly awesome company (seriously &#8212; working at Apple is a blast), please <a href="mailto:bbum@apple.com">send a resume/CV my way</a> and apply for the job through the official channels which can be found by clicking the links below.</p>
<p>The list with very brief descriptions.  Click through for more information.  </p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2373705">2373705: Senior Embedded Systems Engineer</a></b> Help to improve support for iPod development within the Xcode tool-chain.</p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2374115">2374115: Performance Analysis Tools Engineer</a></b> Improve the integration and capabilities of the performance analysis tools included with Xcode.</p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2374098">2374098: Embedded Systems Performance Engineer</a></b> Embedded systems (iPod) focused improvements to the performance analysis tools included with Xcode.</p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2375392">2375392: Distributed Build Engineer</a></b> Help to improve the distributed build feature within Xcode.</p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2374092">2374092: Build Systems Engineer</a></b> Focused on improving the build system within Xcode.  This is <i>not</i> about building Xcode itself, but about refining the code that is run when a developer hits the Build button while running Xcode.</p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2371488">2371488: Xcode Engineer &#8212; Xcode UI</a></b> The Xcode team is seeking an experienced engineer with excellent end user application human interface design skills to conceive, design and develop future enhancements to Xcode and its supporting tools.</p>
<p>The following isn&#8217;t with the Xcode team, but may be of interest to folks interest in contributing to development tools.</p>
<p><b><a href="https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa/wa/jobDescription?RequisitionID=2371718">2371718: Interface Builder Engineer</a></b> Help to improve and extend Interface Builder.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2005/07/21/job-openings-on-the-xcode-team/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PyObjC 1.3.7 Released</title>
		<link>http://www.friday.com/bbum/2005/07/06/pyobjc-137-released/</link>
		<comments>http://www.friday.com/bbum/2005/07/06/pyobjc-137-released/#comments</comments>
		<pubDate>Wed, 06 Jul 2005 20:46:22 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[PyObjC]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=476</guid>
		<description><![CDATA[PyObjC 1.3.7 has been released. It includes: Initial port to Mac OS X for Intel Xcode 2.1 compatibility Support for SenTestingKit and SecurityFoundation frameworks Complete wrappers for DiscRecording framework &#8230; a handful of other bug fixes &#8230; Full details can be found in the NEWS file.]]></description>
			<content:encoded><![CDATA[<p><a href="http://pyobjc.sourceforge.net/"><b>PyObjC 1.3.7</b></a> has been released.</p>
<p>It includes:</p>
<ul>
<li>Initial port to Mac OS X for Intel</li>
<li>Xcode 2.1 compatibility</li>
<li>Support for SenTestingKit and SecurityFoundation frameworks</li>
<li>Complete wrappers for DiscRecording framework</li>
<li>&#8230; a handful of other bug fixes &#8230;</li>
</ul>
<p>Full details can be found in the <a href="http://pyobjc.sourceforge.net/NEWS-1.3.7.txt">NEWS file</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2005/07/06/pyobjc-137-released/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Xcode, file references &amp; build locations</title>
		<link>http://www.friday.com/bbum/2004/12/05/xcode-file-references-build-locations/</link>
		<comments>http://www.friday.com/bbum/2004/12/05/xcode-file-references-build-locations/#comments</comments>
		<pubDate>Mon, 06 Dec 2004 06:08:06 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/2004/12/05/xcode-file-references-build-locations/</guid>
		<description><![CDATA[Within Xcode projects, every file or resource has a reference that instructs Xcode how to find the file. This includes files, resources, build products, dynamic libraries and everything else in the project. These references are both extremely powerful and quite easy to configure incorrectly. Any resource reference can be either via a relative or absolute [...]]]></description>
			<content:encoded><![CDATA[<p>Within <a href="http://www.apple.com/macosx/features/xcode/">Xcode</a> projects, every file or resource has a reference that instructs Xcode how to find the file.  This includes files, resources, build products, dynamic libraries and everything else in the project.</p>
<p>These references are both extremely powerful and quite easy to configure incorrectly.  Any resource reference can be either via a relative or absolute path.   If relative, it can be relative to one of several locations including the project, the enclosing group, or the build directory.</p>
<p>Now, Xcode also has a very useful feature that allows you to specify a location into which all build products and intermediate products will be written.  First and foremost, this will eliminate the noise of the build directory from your workarea.  No more &#8220;? build&#8221; noise from CVS or Subversion.  If you point it to the fastest hard drive on your system, you will also gain the advantage of all the intermediate and final products being written to and read from that fast device.   If you have a boatload of RAM, create a RAM drive and eliminate a huge chunk of disk I/O from the build process.  If using FileVault, moving the build directories will eliminate the overhead of encrypting the files created during the build of the project (with the obvious security sacrifice).</p>
<p><i>Just make sure you get the resource references correct.</i>   In particular, If you have multiple targets and then have a copy files build phase that copies those targets&#8217; products into the product of some other target, <i>make sure you use a build directory relative reference</i>.</p>
<p>A project relative reference will work, but <i>only</i> on your system and <i>only</i> if your build directory never moves relative to your project directory.</p>
<p>And that is the real challenge to resource references.  <b><i>Misconfigured references will work on your machine the first time you set them, but will fail if used in an environment without exactly the same set of paths</i></b>.</p>
<p>To help minimize the problem:</p>
<ul>
<li>Use Xcode&#8217;s preferences to set the intermediate and final build product directories to some place other than the project.  Don&#8217;t use the same path.  I have often set the path to /tmp/build-bbum/intermediate and /tmp/build-bbum/products respectively.   This also guarantees that the projects will be rebuilt after any reboot.  Occasional clean rebuilds often seem to clean up weird issues.</li>
<li>Create a second user account on your system and use Fast User Switching to occasionally bop over, update a workarea and build the project.  This will also rapidly pick up revision control problems, such as forgetting to add a resource to the repository.</li>
<li>Better yet, keep a workarea on a second machine or have a friend do an update and make sure things still build.</li>
</ul>
<p>This came up because I had been playing with Growl and had checked out the source because I wanted to fix a few bugs.   The CopyFiles build phase in the GrowlHelperApp were project relative, but referred to build products, thus assuming that the build directory is always in the same place relative to the project.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2004/12/05/xcode-file-references-build-locations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Mac OS X and Unix Programming</title>
		<link>http://www.friday.com/bbum/2003/06/26/core-mac-os-x-and-unix-programming/</link>
		<comments>http://www.friday.com/bbum/2003/06/26/core-mac-os-x-and-unix-programming/#comments</comments>
		<pubDate>Thu, 26 Jun 2003 09:20:15 +0000</pubDate>
		<dc:creator>bbum</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.friday.com/bbum/?p=541</guid>
		<description><![CDATA[Big Nerd Ranch was kind enough to send me a copy of their new book Core Mac OS X and Unix Programming in gratitude for editing the original Cocoa Programming for Mac OS X book. The book is effectively the course materials for the Big Nerd Ranch course of the same name. Co-authored by Mark [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.bignerdranch.com/">Big Nerd Ranch</a> was kind enough to send me a copy of their new book <a href="http://www.bignerdranch.com/Company/Core_Book_PR.html">Core Mac OS X and Unix Programming</a> in gratitude for editing the original <a href="http://www.bignerdranch.com/Book/">Cocoa Programming for Mac OS X</a> book.</p>
<p>The book is effectively the course materials for the Big Nerd Ranch course of the same name.</p>
<p>Co-authored by Mark Dalrymple and Aaron Hillegass, the book covers many advanced topics in the same clear/concise manner as Aaron&#8217;s original Cocoa programming book.</p>
<p>The book is focused on relatively advanced topics such as memory management, the run loop, multiple processes, rendezvous and many other topics.  Instead of focusing on the high level details, each topic is investigated from the perspective of documenting the technical details&#8211; often non-obvious&#8211; through the use of examples, diagrams and discussions.</p>
<p>Two bits that immediately grabbed my attention&#8211;and are examples of the approach found in the rest of the book&#8211; where the discussion of malloc() behavior and the discussion of the run loop.</p>
<p>In the case of malloc(), the book precisely discusses the fact that malloc() does not necessarily return the number of bytes that you think it does &#8212; it often returns more based on certain internal optimizations.  The end result is that quite a number of memory size reduction related optimizations are a complete waste of time!  Instead, you might be able to consume a few extra bytes by not compressing the data structures and gain raw performance in terms of the # of CPU cycles needed to access the data.</p>
<p>The discussion of the run loop was also of great interest.   It clearly diagrams the run loop and the exact point during the run loop &#8212; both CFRunLoop and NSRunLoop &#8212; that the various events and timers will be handled.</p>
<p>Excellent, excellent stuff.</p>
<p>The $100 price tag is a bit higher than most developer books, but the content is of an advanced and highly refined nature.  $100 is a heck of a lot cheaper than $3,500 &#8212; the entrance fee to the class for which the book was written.</p>
<p>Big Nerd Ranch has also made a set of resources and forums <a href="http://borkware.com/corebook/">available online</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.friday.com/bbum/2003/06/26/core-mac-os-x-and-unix-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

