<?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>Mac / iPhone App Development &#187; multithreading</title>
	<atom:link href="http://benreeves.co.uk/tag/multithreading/feed/" rel="self" type="application/rss+xml" />
	<link>http://benreeves.co.uk</link>
	<description>Home of a Small Time Developer</description>
	<lastBuildDate>Wed, 26 May 2010 14:24:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multithreading with core Data</title>
		<link>http://benreeves.co.uk/multithreading-with-core-data/</link>
		<comments>http://benreeves.co.uk/multithreading-with-core-data/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 17:23:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[core data]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[sqllite]]></category>

		<guid isPermaLink="false">http://benreeves.co.uk/?p=188</guid>
		<description><![CDATA[Working with core data in a multi threaded environment you have to extremely careful
For example if were creating a news application, we want to be able to import news in the background and display updates to the user with no interruption of the GUI. The task can be divided into several stages:

Download the xml feed [...]]]></description>
			<content:encoded><![CDATA[<p>Working with core data in a multi threaded environment you have to extremely careful</p>
<p>For example if were creating a news application, we want to be able to import news in the background and display updates to the user with no interruption of the GUI. The task can be divided into several stages:</p>
<ol>
<li>Download the xml feed with the latest news</li>
<li>Parse the feed</li>
<li>Insert the articles into core data</li>
<li>Notify the UI and refresh the display.</li>
</ol>
<p>We already have our core data API defined. A simple method to retrieve all the articles and a method to add a new article.<br />
DataSource.h</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> DataSource <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> <span style="color: #002200;">&#123;</span> <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>getNewsFor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addArticle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Article<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>article forRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region;
<span style="color: #a61390;">@end</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Now suppose we want to the web service to import the latest articles. We might define our implementation something like this:<br />
WebService.h</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> WebService <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">id</span> delegate;
	LocalDataSource <span style="color: #002200;">*</span> source;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">id</span> delegate;
<span style="color: #a61390;">@property</span><span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> LocalDataSource <span style="color: #002200;">*</span> source;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>importNewsForRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>Our implementation of importNewsForRegion would look something like this:</p>
<p>WebService.m</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>importNewsForRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">//Perform in background if called from main</span>
	 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSThread</span> currentThread<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSThread</span> mainThread<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>self performSelectorInBackground<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>importNewsForRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span> withObject<span style="color: #002200;">:</span>region<span style="color: #002200;">&#93;</span>;
		 <span style="color: #a61390;">return</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Setup pool</span>
	 <span style="color: #400080;">NSAutoreleasePool</span> <span style="color: #002200;">*</span> pool <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAutoreleasePool</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	 <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span> articles <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>XML parseArticleFeed<span style="color: #002200;">:</span>region.feedURL<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">//Not safe 1.</span>
	 <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>Article <span style="color: #002200;">*</span> article <span style="color: #a61390;">in</span> articles<span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>source addArticle<span style="color: #002200;">:</span>article forRegion<span style="color: #002200;">:</span>region<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">//Not safe 2.</span>
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #002200;">&#91;</span>delegate finishedImport<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">//Not safe 3.</span>
	<span style="color: #002200;">&#91;</span>pool drain<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>However this because importNewsForRegion is running in a separate thread this is unsafe and will likely cause core data to crash or corrupt our database.</p>
<ol>
<li>The region passed to to importNews has likely come from a core data context which was constructed on the main thread. Even though were not even altering the region directly with core data it&#8217;s not safe to even read the feedURL, because every operation can trigger faulting.</li>
<li>When we instruct the source to add an article it will use the main threads context, this is fine when we are in the main thread, but in a background thread we need to specify our own context.</li>
<li>Not related to core data, but when we notify the delegate it will likely perform UI updates which are not safe to perform in a background thread. we need to ensure the delegate only received notifications on the main thread.</li>
</ol>
<p>To make our program thread safe we first need to make some small alterations to our API.</p>
<p>DataSource.h</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> DataSource <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> <span style="color: #002200;">&#123;</span> <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>getNewsFor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>getNewsFor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region context<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectContext</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context;
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addArticle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Article<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>article forRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addArticle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Article<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>article forRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region context<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectContext</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context;
<span style="color: #a61390;">@end</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>In our data source we specify two more methods which allow us to provide a context for the method to use. All our queries should be updated to only use the provided context. The original methods that don&#8217;t specify a context should call the newly implemented method with the default context, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addArticle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Article<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>article forRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>region
<span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self addArticle<span style="color: #002200;">:</span>article forRegion<span style="color: #002200;">:</span>region context<span style="color: #002200;">:</span>mainThreadContext<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Only when we are using core data in a background thread do we need to use the newly added methods. So we can now update our WebService.m:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>importNewsForRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>unsafeRegion
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">//Perform in background if called from main</span>
	 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSThread</span> currentThread<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSThread</span> mainThread<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>self performSelectorInBackground<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>importNewsForRegion<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span> withObject<span style="color: #002200;">:</span> unsafeRegion<span style="color: #002200;">&#93;</span>;
		 <span style="color: #a61390;">return</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Setup pool</span>
	 <span style="color: #400080;">NSAutoreleasePool</span> <span style="color: #002200;">*</span> pool <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAutoreleasePool</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Create a new context just for this thread</span>
	<span style="color: #400080;">NSManagedObjectContext</span> <span style="color: #002200;">*</span> managedObjectContext <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectContext</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>managedObjectContext setPersistentStoreCoordinator<span style="color: #002200;">:</span>  <span style="color: #002200;">&#91;</span>source persistentStoreCoordinator<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
        <span style="color: #11740a; font-style: italic;">//Create a new region which is safe to use in this thread</span>
	Region <span style="color: #002200;">*</span> region <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>Region<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>managedObjectContext existingObjectWithID<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>unsafeRegion objectID<span style="color: #002200;">&#93;</span> error<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
	 <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span> articles <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>XML parseArticleFeed<span style="color: #002200;">:</span>region.feedURL<span style="color: #002200;">&#93;</span>;
	 <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>Article <span style="color: #002200;">*</span> article <span style="color: #a61390;">in</span> articles<span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
               <span style="color: #11740a; font-style: italic;">//Ensure we provide the context for the source to use</span>
		<span style="color: #002200;">&#91;</span>source addArticle<span style="color: #002200;">:</span>article forRegion<span style="color: #002200;">:</span>region context<span style="color: #002200;">:</span>managedObjectContext<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">//Save changes and close the new context</span>
	<span style="color: #002200;">&#91;</span>managedObjectContext save<span style="color: #002200;">:&amp;</span>amp;error<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>managedObjectContext release<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>delegate performSelectorOnMainThread<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>finishedImport<span style="color: #002200;">&#41;</span> withObject<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span> waitUntilDone<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>pool drain<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>As you can see we crate a new context using out shared persistentStoreCoordinator, we ensure that anytime we touch core data from this thread we are using this context. The also means that we have to create a new region which belongs to this context, and we do this with the existingObjectWithID method and using the [unsafeRegion objectID]. Finally we ensure that the delegate receives the notification on the main thread.</p>
<p>for more information about threading in core data see:</p>
<p>http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdMultiThreading.html</p>
]]></content:encoded>
			<wfw:commentRss>http://benreeves.co.uk/multithreading-with-core-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
