<?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>Jeff Kelley’s Blog &#187; iPhone</title>
	<atom:link href="http://blog.slaunchaman.com/tag/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.slaunchaman.com</link>
	<description>Mac tips, iPhone applications, and the like</description>
	<lastBuildDate>Fri, 02 Dec 2011 04:51:07 +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>Cocoa Touch: Circumventing UITableViewCell Redraw Issues with Multithreading</title>
		<link>http://blog.slaunchaman.com/2011/08/14/cocoa-touch-circumventing-uitableviewcell-redraw-issues-with-multithreading/</link>
		<comments>http://blog.slaunchaman.com/2011/08/14/cocoa-touch-circumventing-uitableviewcell-redraw-issues-with-multithreading/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 20:14:23 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[iOS Programming]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[UITableViewCell]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=467</guid>
		<description><![CDATA[In your career as a Cocoa or Cocoa Touch developer, every now and then you’ll encounter an issue with something Apple has written. Whether it’s a full-blown bug, something that doesn’t work quite how you’d expect it to, or a minor inconvenience, it happens. When it does, naturally the first thing you do is file [...]]]></description>
			<content:encoded><![CDATA[<p>In your career as a Cocoa or Cocoa Touch developer, every now and then you’ll encounter an issue with something Apple has written. Whether it’s a full-blown bug, something that doesn’t work quite how you’d expect it to, or a minor inconvenience, it happens. When it does, naturally the first thing you do is file <a href="http://bugreport.apple.com">a bug report</a> (<em>right?</em>). After that, though, you need to <em>do something</em> about it. This usually occurs right when a project is due, so often we can’t wait for Apple’s engineering teams to fix the problems (or tell you that you’re wrong). This post is an example of using KVO to get around the problem without worrying about it anymore.</p>
<p><strong>The Problem:</strong> In iOS, if you create a <code>UITableViewCell</code> and return it to the table view in its data source’s <code>-tableView:cellForRowAtIndexPath:</code> method, but then return later (say, after doing some background processing) to add an image to the cell’s <code>imageView</code>, you don’t see anything! Why? Well, it looks like either the image view isn’t added to the cell’s view hierarchy if you don’t immediately add an image or there’s some other bug in the <code>UITableViewCell</code> implementation. I don’t think it’s a bug, I think it’s just a side effect of an optimization; if there’s no image, why add it to the cell?</p>
<p>So how do we fix it? Well, a simple call to <code>-setNeedsLayout</code> gets the cell to fix itself quite nicely. But we shouldn’t have to do that from our table view data source—that has a bit of code smell to it. Lines like that quickly get overused, with programmers calmly stating, “I don’t know why, but we always do that.” No, a better solution is to get the cell to handle this problem on its own.</p>
<p>We’ll create a subclass of UITableViewCell and use KVO. When we create the cell, we’ll register for KVO notifications with the on the image view whenever its <code>image</code> property is modified—but we’ll send the option to include the <em>old</em> value in the change dictionary. When we receive the notification, we’ll look at that dictionary, and if the old value was <code>nil</code>, then we’ll send <code>self</code> a <code>-setNeedsLayout</code> message. This avoids having to do it in other classes, and only does it when necessary. We simply set it and forget it.</p>
<div id="gist-1143494" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="cp">#import &lt;UIKit/UIKit.h&gt;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="k">@interface</span> <span class="nc">JKTableViewCell</span> : <span class="nc">UITableViewCell</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="k">@end</span></div><div class='line' id='LC7'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1143494/a53db908610a1504ee6b7b9cc120fa0a39e68e0e/JKTableViewCell.h" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1143494#file_jk_table_view_cell.h" style="float:right;margin-right:10px;color:#666">JKTableViewCell.h</a>
            <a href="https://gist.github.com/1143494">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="cp">#import &quot;JKTableViewCell.h&quot;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="k">@implementation</span> <span class="nc">JKTableViewCell</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="k">-</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nf">initWithStyle:</span><span class="p">(</span><span class="n">UITableViewCellStyle</span><span class="p">)</span><span class="nv">style</span> <span class="nf">reuseIdentifier:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">reuseIdentifier</span></div><div class='line' id='LC7'><span class="p">{</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="nl">initWithStyle:</span><span class="n">style</span> <span class="nl">reuseIdentifier:</span><span class="n">reuseIdentifier</span><span class="p">];</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">[[</span><span class="n">self</span> <span class="n">imageView</span><span class="p">]</span> <span class="nl">addObserver:</span><span class="n">self</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">forKeyPath:</span><span class="s">@&quot;image&quot;</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">options:</span><span class="n">NSKeyValueObservingOptionOld</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">context:</span><span class="nb">NULL</span><span class="p">];</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">self</span><span class="p">;</span></div><div class='line' id='LC18'><span class="p">}</span></div><div class='line' id='LC19'><br/></div><div class='line' id='LC20'><span class="c1">// The reason we’re observing changes is that if you create a table view cell, return it to the</span></div><div class='line' id='LC21'><span class="c1">// table view, and then later add an image (perhaps after doing some background processing), you</span></div><div class='line' id='LC22'><span class="c1">// need to call -setNeedsLayout on the cell for it to add the image view to its view hierarchy. We</span></div><div class='line' id='LC23'><span class="c1">// asked the change dictionary to contain the old value because this only needs to happen if the</span></div><div class='line' id='LC24'><span class="c1">// image was previously nil.</span></div><div class='line' id='LC25'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">observeValueForKeyPath:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">keyPath</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nf">ofObject:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">object</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nf">change:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">change</span></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nf">context:</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="nv">context</span></div><div class='line' id='LC29'><span class="p">{</span></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="n">object</span> <span class="o">==</span> <span class="p">[</span><span class="n">self</span> <span class="n">imageView</span><span class="p">]</span> <span class="o">&amp;&amp;</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">[</span><span class="n">keyPath</span> <span class="nl">isEqualToString:</span><span class="s">@&quot;image&quot;</span><span class="p">]</span> <span class="o">&amp;&amp;</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">([</span><span class="n">change</span> <span class="nl">objectForKey:</span><span class="n">NSKeyValueChangeOldKey</span><span class="p">]</span> <span class="o">==</span> <span class="nb">nil</span> <span class="o">||</span></div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">[</span><span class="n">change</span> <span class="nl">objectForKey:</span><span class="n">NSKeyValueChangeOldKey</span><span class="p">]</span> <span class="o">==</span> <span class="p">[</span><span class="n">NSNull</span> <span class="n">null</span><span class="p">]))</span> <span class="p">{</span></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">[</span><span class="n">self</span> <span class="n">setNeedsLayout</span><span class="p">];</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC36'><span class="p">}</span></div><div class='line' id='LC37'><br/></div><div class='line' id='LC38'><span class="k">@end</span></div><div class='line' id='LC39'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1143494/90294445f0b984f4f823911404a14dca57d652ad/JKTableViewCell.m" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1143494#file_jk_table_view_cell.m" style="float:right;margin-right:10px;color:#666">JKTableViewCell.m</a>
            <a href="https://gist.github.com/1143494">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2011/08/14/cocoa-touch-circumventing-uitableviewcell-redraw-issues-with-multithreading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GCD Example Updated (Now With More Speed!)</title>
		<link>http://blog.slaunchaman.com/2011/08/12/gcd-example-updated-now-with-more-speed/</link>
		<comments>http://blog.slaunchaman.com/2011/08/12/gcd-example-updated-now-with-more-speed/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 04:03:57 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[iOS Programming]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Grand Central Dispatch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[UIImage]]></category>
		<category><![CDATA[updates]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=463</guid>
		<description><![CDATA[Due to popular demand, I’ve updated my GCD example from previous talks to include a few things to make the example not only do something on a background queue, but also snappy. It should scroll much better now. A quick rundown of what changed: Images are now resized. Since the example uses wallpaper-sized images, there’s [...]]]></description>
			<content:encoded><![CDATA[<p>Due to popular demand, I’ve updated <a href="https://github.com/SlaunchaMan/GCDExample">my GCD example</a> from previous talks to include a few things to make the example not only do something on a background queue, but also snappy. It should scroll much better now. A quick rundown of what changed:</p>
<ul>
<li><strong>Images are now resized.</strong> Since the example uses wallpaper-sized images, there’s no sense in <em>not</em> resizing them to go on a 44-pixel-tall table view cell. I’m using the popular image-resizing routines from <a href="http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/" target="_blank">Trevor’s Bike Shed</a> to do the resizing with a nice interpolation quailty.</li>
<li><strong>Those resized images are now cached.</strong> I use an <code>NSCache</code> to store the images. If the app receives a memory warning, it’ll jettison all of the cached images, but if you’re just scrolling up and down this is a quick and dirty way to cache the images. I had never really used <code>NSCache</code> before, so this was a good excuse to try it.</li>
</ol>
<p>I’m at <a href="http://www.cocoaconf.com" target="_blank">CocoaConf</a> in that state down to the South today, so this post has been brought to you by late-night hotel room caffeine. I made some other changes to the project to deal with a weird table view cell bug that I’ve submitted to Apple; a post on that is coming up next!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2011/08/12/gcd-example-updated-now-with-more-speed/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iOS Programming for Multicore Processors</title>
		<link>http://blog.slaunchaman.com/2011/03/03/ios-programming-for-multicore-processors/</link>
		<comments>http://blog.slaunchaman.com/2011/03/03/ios-programming-for-multicore-processors/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 02:54:31 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[Mac Programming]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Grand Central Dispatch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=417</guid>
		<description><![CDATA[With the impending release of the iPad 2, understanding how to program multithreaded applications will quickly become paramount as applications continue to push the envelope to make immersive experiences with high-performance computation. Now, without actually having a multicore iPad in my hands, I can’t say exactly how the system will behave, but there are a [...]]]></description>
			<content:encoded><![CDATA[<p>With the impending release of <a href="http://www.apple.com/ipad/">the iPad 2</a>, understanding how to program multithreaded applications will quickly become paramount as applications continue to push the envelope to make immersive experiences with high-performance computation. Now, without actually <em>having</em> a multicore iPad in my hands, I can’t say exactly how the system will behave, but there are a few best practices we should all be aware of when writing iOS code:</p>
<ul>
<li><strong>Using <a href="http://developer.apple.com/library/mac/#referencelibrary/GettingStarted/GettingStartedWithCoreData/">Core Data</a>?</strong> You can’t share access to an <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/"><code>NSManagedObjectContext</code></a> across multiple threads, <a href="http://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html">dispatch queues</a>, or <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperationQueue_class/"><code>NSOperation</code> queues</a>, so for each one you’ll need to create a new instance. Similarly, don’t pass an <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/"><code>NSManagedObject</code></a> or subclass thereof between threads. Give each of your objects a unique ID—<a href="http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFUUIDRef/Reference/reference.html"><code>CFUUID</code></a> works well for this—and pass the ID around, pulling a new object out of your <code>NSManagedObjectContext</code> for each thread. It’s a pain, but that’s how to (safely) get around threading and Core Data.</li>
<li><strong><em>Always</em> call UIKit updates from the main thread.</strong> Whatever you’re doing to your user interface, be it updating a label, loading an image into an image view, <em>anything</em> that’ll be rendered to screen—and some things that won’t—should be run on the main thread. There are two main ways to do this:
<ol>
<li><em>Use Grand Central Dispatch.</em> Using <a href="http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dispatch_get_main_queue.3.html"><code>dispatch_get_main_queue()</code></a>, you can get a reference to the main queue and submit blocks to it for updating your UI. This is typically a clean, easy way to refactor existing code for thread-aware programming.</li>
<li><em>Use <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone:"><code>-performSelectorOnMainThread:withObject:waitUntilDone:</code></a> and friends.</em> This has the drawback of only working for methods that take one or zero Objective-C objects as arguments, but can be a quick and easy way to use fire-and-forget methods like <a href="http://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/reloadData"><code>-reloadData</code></a> on <a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html"><code>UITableView</code></a>.</li>
</ol>
</li>
<li><strong>Think about how you declare your properties.</strong> How many people have been using atomic properties? Before now, not many. In fact, before now, it was typically useless, as the chances of something interrupting your accessor methods was pretty low. Now, though, if you’re planning on accessing an object from multiple threads, you <em>really</em> need to control access to your properties.</li>
<li><strong>Use locks.</strong> Locks, long the scourge of the multithreaded-code author, are simply essential for some parts of multithreaded programming. Whether you’re using <a href="http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSLock_Class/Reference/Reference.html"><code>NSLock</code></a> or a lower-level lock, or even something like Grand Central Dispatch’s counting semaphore type, <a href="http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/doc/uid/TP40008079-CH2-SW37"><code>dispatch_semaphore_t</code></a>, protect critical regions of your code from multiple accessors with (carefully-thought-out) locked access.</li>
</ul>
<p>This list is by no means exhaustive, and Apple can do a lot to make this irrelevant (such as make UIKit threadsafe, which would be a <em>killer</em> iOS 5.0 feature), but with the iPad 2’s arrival, developers can no longer assume safety from threading problems. Be sure also to read Apple’s <a href="http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/">Threading Programming Guide</a> to get anything I’ve left out.</p>
<p>It also makes a great excuse to buy an iPad 2. I mean, you need to <em>test</em> this, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2011/03/03/ios-programming-for-multicore-processors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocoa Touch Tutorial: Using Grand Central Dispatch for Asynchronous Table View Cells</title>
		<link>http://blog.slaunchaman.com/2011/02/28/cocoa-touch-tutorial-using-grand-central-dispatch-for-asynchronous-table-view-cells/</link>
		<comments>http://blog.slaunchaman.com/2011/02/28/cocoa-touch-tutorial-using-grand-central-dispatch-for-asynchronous-table-view-cells/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 02:23:25 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[Mac Programming]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Blocks]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[Grand Central Dispatch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[UITableView]]></category>
		<category><![CDATA[UITableViewCell]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=403</guid>
		<description><![CDATA[One of the problems that an iOS developer will often face is the performance of table view cells. Table view cells are loaded on-demand by the UITableView that they’re a part of; the system calls &#8209cellForRowAtIndexPath: on the table view’s dataSource property to fetch a new cell in order to display it. Since this method [...]]]></description>
			<content:encoded><![CDATA[<p>One of the problems that an iOS developer will often face is the performance of table view cells. Table view cells are loaded on-demand by the <code>UITableView</code> that they’re a part of; the system calls <code>&#8209cellForRowAtIndexPath:</code> on the table view’s <code>dataSource</code> property to fetch a new cell in order to display it. Since this method is called (several times) while scrolling a table view, it needs to be very performant. You don’t have very much time to provide the system with a table view cell; take too long, and the application will appear to stutter to your users. This kills the immersion of your application and is an instant sign to users that the application is poorly-written. I guess what I’m saying is that this code needs to be <em>fast</em>. But what if something you need to do to display the table view cell takes a long time—say, loading an image?</p>
<p>In <a href="http://blog.slaunchaman.com/2011/02/19/mobidevday-presentation-slides/">my MobiDevDay presentation</a> a couple of weeks ago, I illustrated a solution to this problem: Grand Central Dispatch. GCD, Apple’s new multiprocessing API in Mac OS X Snow Leopard and iOS 4, is the perfect solution for this problem. Let’s take a look at how it works.</p>
<p>Grand Central Dispatch operates using queues. Queues are a C typedef: <code>dispatch_queue_t</code>. To get a new global queue, we call <code>dispatch_get_global_queue()</code>, which takes two arguments: a <code>long</code> for priority and an <code>unsigned long</code> for options, which is unused, so we’ll pass <code>0ul</code>. Here’s how we get a high-priority queue:</p>
<pre class="brush: objc; gutter: false; title: ; notranslate">dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);</pre>
<p>It’s pretty straightforward. To use this queue, we add blocks of code onto it. Typically this is done with blocks (Apple’s new code encapsulation extension to the C language), though it can be done with C functions. To submit a block onto a queue for execution, use the functions <code>dispatch_sync</code> and <code>dispatch_async</code>. They both take a queue and a block as parameters. <code>dispatch_async</code> returns immediately, running the block asynchronously, while <code>dispatch_sync</code> blocks execution until the provided block returns (though you cannot use its return value). Here’s how we schedule some code onto a queue (we’ll assume this code runs after our previous example, so <code>queue</code> is already defined):</p>
<pre class="brush: objc; gutter: false; title: ; notranslate">dispatch_async(queue, ^{
    NSLog(@&quot;Hello, World!&quot;);
});</pre>
<p>It’s very easy to forget the <code>);</code> at the end of that line, so be careful.</p>
<p>How does this apply to table view cells? Let’s take a look at a typical scenario for loading images from disk:</p>
<pre class="brush: objc; first-line: 33; title: ; notranslate">- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @&quot;ExampleCell&quot;;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier] autorelease];
    }

    // Get the filename to load.
    NSString *imageFilename = [imageArray objectAtIndex:[indexPath row]];
    NSString *imagePath = [imageFolder stringByAppendingPathComponent:imageFilename];

    [[cell textLabel] setText:imageFilename];
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    [[cell imageView] setImage:image];

    return cell;
}</pre>
<p>The problem with that code is that creating <code>image</code> blocks until <code>&#8209imageWithContentsOfFile:</code> returns. If the images are especially large, this is catastrophic. Modifying this code to use Grand Central Dispatch is simple:</p>
<pre class="brush: objc; first-line: 33; title: ; notranslate">- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @&quot;Cell&quot;;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier] autorelease];
    }

    // Get the filename to load.
    NSString *imageFilename = [imageArray objectAtIndex:[indexPath row]];
    NSString *imagePath = [imageFolder stringByAppendingPathComponent:imageFilename];

    [[cell textLabel] setText:imageFilename];

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

    dispatch_async(queue, ^{
        UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

        dispatch_sync(dispatch_get_main_queue(), ^{
            [[cell imageView] setImage:image];
            [cell setNeedsLayout];
        });
    });

    return cell;
}</pre>
<p>First, we create our image asynchronously by using <code>dispatch_async()</code>. Once we have it, however, we have to come back to the main thread in order to update our table view cell’s UI (all UI updates should be on the main thread, unless you like reading crash reports). GCD has a function to get the main queue—analogous to the main thread—called <code>dispatch_get_main_queue()</code>. We can dispatch a block to <em>that</em> thread to update the UI.</p>
<p>By making this simple modification, we can very easily improve the performance of our table view. There are a few steps remaining, however, and this method has one serious shortcoming: if the cell is re-used by the time the image loads, it can load the wrong image into the cell. To get around this, it would be better to cache the images in an array or a dictionary (just be sure to release it in your view controller’s <code>&#8209didReceiveMemoryWarning:</code> method). That said, this is an example of something you can do quite easily to improve the performance of your application. The better it performs, the more your users will like it, and that’s the ultimate goal.</p>
<p>The code used in this post is available as a <a href="https://github.com/SlaunchaMan/GCDExample">GitHub</a> repository.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2011/02/28/cocoa-touch-tutorial-using-grand-central-dispatch-for-asynchronous-table-view-cells/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>MobiDevDay Presentation Slides</title>
		<link>http://blog.slaunchaman.com/2011/02/19/mobidevday-presentation-slides/</link>
		<comments>http://blog.slaunchaman.com/2011/02/19/mobidevday-presentation-slides/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 19:39:06 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[Mac Programming]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Blocks]]></category>
		<category><![CDATA[Grand Central Dispatch]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=394</guid>
		<description><![CDATA[I gave a presentation on blocks and Grand Central Dispatch today at MobiDevDay. You can download the slides at SlideShare. Looking for more reading about blocks? Here are some more resources: Programming with C Blocks by Joachim Bengtsson Introducting Blocks and Grand Central Dispatch by Apple Blocks Programming Topics by Apple Also, as we saw [...]]]></description>
			<content:encoded><![CDATA[<p>I gave a presentation on blocks and Grand Central Dispatch today at MobiDevDay. You can download the slides <a href="http://slidesha.re/dTeoXj">at SlideShare</a>.</p>
<p>Looking for more reading about blocks? Here are some more resources:</p>
<ul>
<li><a href="http://thirdcog.eu/pwcblocks/">Programming with C Blocks by Joachim Bengtsson</a></li>
<li><a href="https://developer.apple.com/library/mac/#featuredarticles/BlocksGCD/">Introducting Blocks and Grand Central Dispatch by Apple</a></li>
<li><a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html">Blocks Programming Topics by Apple</a></li>
</ul>
<p>Also, as we saw in the presentation, check out <a href="http://www.cdecl.org">cdecl.org</a> to cheat!</p>
<p><strong>UPDATE:</strong> Looking for example code? I’ve put some of the code that went into the slides <a href="https://github.com/SlaunchaMan/iOSBlocksPresentation">up on GitHub</a>. It’s light, but it also includes a .PDF version of the presentation.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2011/02/19/mobidevday-presentation-slides/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone Programming: Hard Mode</title>
		<link>http://blog.slaunchaman.com/2011/02/05/iphone-programming-hard-mode/</link>
		<comments>http://blog.slaunchaman.com/2011/02/05/iphone-programming-hard-mode/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 16:14:19 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Objective-C Runtime]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=375</guid>
		<description><![CDATA[After a conversation with some co-workers, I discussed how it would be technically possible to write an iPhone app using only a main.m file—no separate class files. This post is the result of that. It’s definitely doable, but not something I’d ever recommend for shipping code. The code is explained below, but you can get [...]]]></description>
			<content:encoded><![CDATA[<p>After a conversation with some co-workers, I discussed how it would be technically possible to write an iPhone app using only a <tt>main.m</tt> file—no separate class files. This post is the result of that. It’s definitely doable, but not something I’d ever recommend for shipping code.<br />
The code is explained below, but you can get the full source in <a href="https://github.com/SlaunchaMan/iPhoneHardMode">my public GitHub repository</a>.</p>
<h2>Getting Started</h2>
<p>By default, an iPhone application template gives you a <tt>main.m</tt> file, but it’s pretty basic:</p>
<pre class="brush: objc; first-line: 9; title: ; notranslate">#import &lt;UIKit/UIKit.h&gt;

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}</pre>
<p>To go from that code to running your application, a few things happen, mostly in <code>UIApplicationMain</code>. Its last argument, typically <code>nil</code>, is a pointer to an <code>NSString</code> that specifies the class name of the application delegate. Normally, your <tt>Info.plist</tt> file specifies a nib file (the keys <code>NSMainNibFile</code> or <code>NSMainNibFile~ipad</code>), which in turn specifies the application delegate, instantiates it, etc.</p>
<p>So, first, delete the <tt>MainWindow.xib</tt> file, then all other class files (<tt>MyCoolAppDelegate.h</tt> and <tt>MyCoolAppDelegate.m</tt>, for instance). There should be three files left in the iPhone application: your <tt>Prefix.pch</tt> file (which we could technically do without), <tt>main.m</tt>, and your <tt>Info.plist</tt> file.</p>
<h2>The Fun Begins</h2>
<h3>Administrivia: Creating Strings</h3>
<p>Since, as a part of the exercise, we don’t want to use Objective-C, I also decided against using any constant <code>NSString</code>s (<code>@"Hello, World!"</code> and the like). To create a string, then, we’ll use <code>CFString</code>s. I created a macro to create one from a C string using ASCII encoding:</p>
<pre class="brush: objc; first-line: 16; title: ; notranslate">#define JK_EasyCFString(X)
(CFStringCreateWithCString(kCFAllocatorDefault, (X), kCFStringEncodingASCII))</pre>
<p>Don’t forget to call <code>CFRelease()</code> when you’re done with it, though.</p>
<h3>Creating a Class</h3>
<p>We need to modify the call to <code>UIApplicationMain</code> to include our application delegate class if we want this app to be anything more than a blank screen. What class name can we give it, though? We’ll need to create a class, and we’ll call it “<code>HardModeAppDelegate</code>.”</p>
<pre class="brush: objc; first-line: 41; highlight: [42]; title: ; notranslate">	// Create a class to serve as our application delegate.
	Class appDelegate = objc_allocateClassPair(NSClassFromString((id)NSObjectString), &quot;HardModeAppDelegate&quot;, 0);</pre>
<p>The first argument is a toll-free bridged <code>CFString</code> that specifies <code>NSObject</code> as the superclass, then we pass in the name of the class as a C string and 0 for the number of extra bytes we want (which is nearly always zero). Now let’s set it up a bit:</p>
<pre class="brush: objc; first-line: 44; highlight: [46,49,50,51,52,65]; title: ; notranslate">	// Conform to the UIApplciationDelegate protocol.
	Protocol *appDelegateProto = NSProtocolFromString((id)UIApplicationDelegateString);
	class_addProtocol(appDelegate, appDelegateProto);

	// Add methods.
	SEL applicationDidFinishLaunchingWithOptions = NSSelectorFromString((id)appDidFinishLaunchingOptionsString);
	class_addMethod(appDelegate,
					applicationDidFinishLaunchingWithOptions,
					(IMP)UIApplicationDelegate_ApplicationDidFinishLaunchingWithOptions,
					&quot;v@:@@&quot;);

	SEL dealloc = NSSelectorFromString((id)deallocString);
	class_addMethod(appDelegate,
					dealloc,
					(IMP)appDelegate_dealloc,
					&quot;v@:&quot;);

	// Add an instance variable for the window.
	class_addIvar(appDelegate,
				  &quot;window&quot;,
				  sizeof(id),
				  log2(sizeof(id)),
				  &quot;@&quot;);

	// Now that we’ve added ivars, we can register the class.
	objc_registerClassPair(appDelegate);</pre>
<p>That code is the same as writing an <code>@interface</code> block for a new class, setting up ivars, conforming to protocols, and defining instance methods, but done using the runtime calls instead. Methods are actually C functions, but with two arguments prepended to the argument list: <code>id self</code> and <code>SEL _cmd</code>. Those arguments are actually passed to <em>every</em> Objective-C method, but usually hidden.</p>
<h3>Custom Message Sending</h3>
<p>The rest of the application is more of this bootstrapped Objective-C in C, but there are a few wrinkles worth discussing, most notably the use of <code>objc_msgSend</code> with methods that return other than <code>id</code> and/or have additional arguments beyond <code>self</code> and <code>_cmd</code>. For instance, to call <code>-bounds</code> on a <code>UIScreen</code> object, I had to cast the return type of <code>objc_msgSend</code> to <code>CGRect</code>:</p>
<pre class="brush: objc; first-line: 134; highlight: [135]; title: ; notranslate">CGRect (*msgSendBounds)(id self, SEL _cmd);
  msgSendBounds = (CGRect(*)(id, SEL))objc_msgSend_stret;</pre>
<p>Similarly, when calling <code>-initWithFrame:</code> on a <code>UIWindow</code> or <code>UILabel</code>, I casted it to take in a <code>CGRect</code> argument:</p>
<pre class="brush: objc; first-line: 141; highlight: [142]; title: ; notranslate">id (*msgSendCGRect)(id self, SEL _cmd, CGRect rect);
msgSendCGRect = (id(*)(id, SEL, CGRect))objc_msgSend;</pre>
<h3>Accessing Instance Variables</h3>
<p>In my implementation of the <code>HardModeAppDelegate</code> class’s <code>-dealloc</code> method, I need to access the <code>window</code> instance variable to send it a <code>-release</code> message. Using the <code>Ivar</code> type and the <code>object_getIvar</code> function, it becomes easy:</p>
<pre class="brush: objc; first-line: 196; title: ; notranslate">Ivar windowIvar = class_getInstanceVariable(self-&gt;isa, &quot;window&quot;);
id window = object_getIvar(self, windowIvar);</pre>
<h2>So what do we have?</h2>
<p>To be clear, this is <em>not</em> writing an iPhone app without using Objective-C, per se. The runtime is still being used, messages are being sent, all that. But it <em>is</em> an illustration of some of the heavy lifting that the runtime does for you. I would caution against adopting this practice for real, shipping apps.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2011/02/05/iphone-programming-hard-mode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Take Me Home</title>
		<link>http://blog.slaunchaman.com/2010/12/18/take-me-home/</link>
		<comments>http://blog.slaunchaman.com/2010/12/18/take-me-home/#comments</comments>
		<pubDate>Sat, 18 Dec 2010 05:09:55 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[My Software]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Take Me Home]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=349</guid>
		<description><![CDATA[Take Me Home was a good “Hello, World!” iOS app, but its time has come. I’ve pulled Take Me Home from the App Store. Goodnight, sweet prince.]]></description>
			<content:encoded><![CDATA[<p>Take Me Home was a good “Hello, World!” iOS app, but its time has come. I’ve pulled Take Me Home from the App Store. Goodnight, sweet prince.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2010/12/18/take-me-home/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Autorelease is Not Your Friend</title>
		<link>http://blog.slaunchaman.com/2010/11/16/autorelease-is-not-your-friend/</link>
		<comments>http://blog.slaunchaman.com/2010/11/16/autorelease-is-not-your-friend/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 05:00:15 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[autorelease]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cocoa Touch]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[NSAutoreleasePool]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=334</guid>
		<description><![CDATA[How many times have you written this line? NSMutableArray *foo = [[[NSMutableArray alloc] init] autorelease]; At first glance, it looks fine. foo is an autoreleased NSMutableArray that you can use and, at the end of the method, it’s gone into the ether of the autorelease pool. Don’t get me wrong, most of the time, this [...]]]></description>
			<content:encoded><![CDATA[<p>How many times have you written this line?</p>
<blockquote><p><code>NSMutableArray *foo = [[[NSMutableArray alloc] init] autorelease];</code></p></blockquote>
<p>At first glance, it looks fine. <code>foo</code> is an autoreleased <code>NSMutableArray</code> that you can use and, at the end of the method, it’s gone into the ether of the autorelease pool. Don’t get me wrong, <em>most of the time</em>, this use of <code>-autorelease</code> is acceptable. But, in this post, I’ll try to convince you to use autorelease differently in subtle ways.<span id="more-334"></span></p>
<h3>Avoid Enormous Pools</h3>
<p>Back to the first line of code. Let’s look at a real-world example of using <code>-autorelease</code> this way:</p>
<blockquote><p><code>
<pre>- (void)doSomeStuffWithAHugeArray:(NSArray *)array
{
    for (NSUInteger i = 0; i &lt; [array count]; i++) {
        NSDictionary *aDict = (NSDictionary *)[array objectAtIndex:i];

        NSMutableArray *foo = [[[NSMutableArray alloc] init] autorelease];
        [foo addObject:[aDict objectForKey:@"someKey"]];

        // Some general processing of foo here.
    }
}</pre>
<p></code></p></blockquote>
<p>To the programmer, this appears perfectly valid. <code>foo</code> will be created once for each object in <code>array</code> and some processing will occur on it. You don’t need to worry about memory management since it’s autoreleased, right?</p>
<p>Right?</p>
<p>But what happens if there are 4 million items in this array? And you’re running on an iPhone? See, the problem with autorelease pools is that they drain their contents at some future point in the run loop. During your methods’ stack frame, the app never returns to the run loop. These objects keep getting added to the autorelease pool, and until the method is done, they don’t go anywhere. On the Mac this isn’t as much of an issue, since unused objects will get paged out of active memory, but on iOS, your app will be terminated when you run out of memory.</p>
<p>What to do? There are two approaches: first, implement a counter:</p>
<blockquote><p><code>
<pre>NSAutoreleasePool *pool = nil;
NSUInteger count = 0;

for (NSUInteger i = 0; i &lt; [array count]; i++) {
    if (pool == nil) {
        pool = [[NSAutoreleasePool alloc] init];
    }

    static NSUInteger count = 0;
    NSDictionary *aDict = (NSDictionary *)[array objectAtIndex:i];

    NSMutableArray *foo = [[[NSMutableArray alloc] init] autorelease];
    [foo addObject:[aDict objectForKey:@"someKey"]];

    // Some general processing of foo here.

    count++;
    if (count % 1000 == 0) {
        // count is a multiple of 1,000
        [pool drain];
        pool = nil;
    }
}
[pool drain];</pre>
<p></code></p></blockquote>
<p>What have we gained, aside from a lot more code? Every 1,000 iterations through this loop, the autorelease pool that we’ve created drains its contents; this eliminates the possibility of millions of <code>NSMutableArray</code>s littering the contents of memory. In this case it’s unnecessary as we could just release <code>foo</code> at the end of the loop, but in most cases you’ll be dealing with other methods, either your own or those provided by Cocoa Touch or some library, that return autoreleased objects. This method prevents those objects from gumming up the works too much. As an example, if you’re processing JSON—let’s say Reddit comments—you can easily get millions of autoreleased <code>NSString</code> objects created, and significant processing of them can become unwieldy.</p>
<h3>Treat <code>-autorelease</code> like <code>-release</code></h3>
<p>Here’s another typical pattern you see in Objective-C code:</p>
<blockquote><p><code>
<pre>MyAwesomeObject *bar = [[[MyAwesomeObject alloc] init] autorelease];
[NSThread detachNewThreadSelector:@selector(extraLongComputation:)
                         toTarget:self
                       withObject:bar];
bar.someProperty = 42;</pre>
<p></code></p></blockquote>
<p>That looks OK at first, but depending on how your app is running, you could be adding <code>bar</code> to an autorelease pool that is drained while <code>-extraLongComputation</code> is running. If you’re performing selectors after a delay or using an <code>NSTimer</code>, this is especially likely. In this case, I like to treat <code>-autorelease</code> like <code>-release</code>:</p>
<blockquote><p><code>
<pre>MyAwesomeObject *bar = [[MyAwesomeObject alloc] init];
[NSThread detachNewThreadSelector:@selector(extraLongComputation:)
                         toTarget:self
                       withObject:bar];
bar.someProperty = 42;
[bar autorelease];</pre>
<p></code></p></blockquote>
<p>By itself, this isn’t sufficient. However, when coupled with this code:</p>
<blockquote><p><code>
<pre>- (void)extraLongComputation:(MyAwesomeObject *)obj
{
    [obj retain];

    // TODO: write computation code.

    [obj release];
}</pre>
<p></code></p></blockquote>
<p>This ensures that <code>bar</code> survives long enough for your computation.</p>
<p>Nothing I’ve written here is a panacea, and I’m sure it’s all been written before (and probably better), but my hope is to at least encourage you to think more about the memory management of your application, lest you find yourself debugging odd crashes the night before a deadline.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2010/11/16/autorelease-is-not-your-friend/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dealing with Special Characters in iPhone 4 Graphics Filenames with Subversion</title>
		<link>http://blog.slaunchaman.com/2010/07/10/dealing-with-special-characters-in-iphone-4-graphics-filenames-with-subversion/</link>
		<comments>http://blog.slaunchaman.com/2010/07/10/dealing-with-special-characters-in-iphone-4-graphics-filenames-with-subversion/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 01:48:27 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[command-line]]></category>
		<category><![CDATA[convenience]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPhone 4]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=304</guid>
		<description><![CDATA[With the iPhone 4’s high-resolution screen, designers need to create two sets of art; the guidelines are to name the files like so: SomeCoolImage.png and SomeCoolImage@2x.png. Unfortunately, if you try to add these files to an SVN repository, the @ symbol throws them off: $ svn add Icon\@2x~iphone.png svn: warning: 'Icon' not found The fix, [...]]]></description>
			<content:encoded><![CDATA[<p>With the iPhone 4’s high-resolution screen, designers need to create two sets of art; the guidelines are to name the files like so: <code>SomeCoolImage.png</code> and <code>SomeCoolImage@2x.png</code>. Unfortunately, if you try to add these files to an SVN repository, the <code>@</code> symbol throws them off:</p>
<blockquote><pre>$ svn add Icon\@2x~iphone.png
svn: warning: 'Icon' not found</pre>
</blockquote>
<p>The fix, thanks to the <a href="http://groups.google.com/group/subversion_users/browse_thread/thread/2b8e8e05e04fa240/">subversion_users Google Group</a>, is to add another <code>@</code> to the end of the filename, like so:</p>
<blockquote><pre>$ svn add ./Icon\@2x~iphone.png@
A  (bin)  Icon@2x~iphone.png</pre>
</blockquote>
<p>If you’d like to do this for all of your high-resolution art in a folder, here’s a tiny Bash command for the task:</p>
<blockquote><pre>for x in `ls *\@*`; do svn add $x\@; done</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2010/07/10/dealing-with-special-characters-in-iphone-4-graphics-filenames-with-subversion/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Take Me Home Now Free</title>
		<link>http://blog.slaunchaman.com/2010/05/10/take-me-home-now-free/</link>
		<comments>http://blog.slaunchaman.com/2010/05/10/take-me-home-now-free/#comments</comments>
		<pubDate>Tue, 11 May 2010 04:12:41 +0000</pubDate>
		<dc:creator>Jeff Kelley</dc:creator>
				<category><![CDATA[My Software]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[shameless plug]]></category>
		<category><![CDATA[Take Me Home]]></category>
		<category><![CDATA[updates]]></category>

		<guid isPermaLink="false">http://blog.slaunchaman.com/?p=267</guid>
		<description><![CDATA[Take Me Home is an ancient, buggy iPhone app that was my &#8220;Hello, World!&#8221; in the App Store. Its sale rate has plummeted to only a couple of buyers a week and, with the prevalence of real, honest-to-God GPS apps in the store these days, its usefulness is questionable. So from here on out, it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.slaunchaman.com/my-software/take-me-home/">Take Me Home</a> is an ancient, buggy iPhone app that was my &ldquo;Hello, World!&rdquo; in the App Store. Its sale rate has plummeted to only a couple of buyers a week and, with the prevalence of real, honest-to-God GPS apps in the store these days, its usefulness is questionable. So from here on out, it&#8217;s free. I can&#8217;t promise to continue supporting it&mdash;especially for new devices and APIs&mdash;so the best I can do may be to remove it from the store in the event that some update breaks it.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.slaunchaman.com/2010/05/10/take-me-home-now-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

