<?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>akosma software &#187; Tech</title> <atom:link href="http://akosma.com/category/tech/feed/" rel="self" type="application/rss+xml" /><link>http://akosma.com</link> <description>Leading international provider of cross-platform and multilingual software solutions, for iPhone, iPad, Mac, Windows, Linux, Android, and the web.</description> <lastBuildDate>Mon, 06 Feb 2012 18:24:31 +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>Determining Delegate Object Method Call Order in Objective-C with NSProxy</title><link>http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/</link> <comments>http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/#comments</comments> <pubDate>Tue, 31 Jan 2012 10:50:53 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Tech]]></category> <category><![CDATA[code]]></category> <category><![CDATA[Education]]></category> <category><![CDATA[iOS]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3364</guid> <description><![CDATA[This is a guest post + code, wrote together with Joe D&#8217;Andrea from LiquidJoe LLC! Many developers new to the iOS platform have trouble understanding the delegate architecture, in the sense that many other OO toolkits use properties to configure the characteristics of UI elements, instead of having a separate object doing the job. When [...]]]></description> <content:encoded><![CDATA[<p>This is a guest post + code, wrote together with <a
href="https://github.com/jdandrea">Joe
D&#8217;Andrea</a> from <a
href="http://www.liquidjoe.biz/">LiquidJoe
LLC</a>!</p><p>Many developers new to the iOS platform have trouble understanding the
delegate architecture, in the sense that many other OO toolkits use
properties to configure the characteristics of UI elements, instead of
having a separate object doing the job.</p><p>When using delegates, the sequence of calls for each method is
important: most Cocoa developers know that UITableView instances call
delegate and data source methods roughly in this order:</p><ul><li>numberOfSections:</li><li>numberOfRows:inSection:</li><li>cellForRowAtIndexPath:</li><li>configureCellAtIndexPath:</li></ul><p>&#8230;mixing up in the middle some calls to headers and footers and cell
sizes as well. Which prompts the following question: <strong>what is really
going on behind the scenes? Can we know exactly the order in which those
delegate methods are called?</strong></p><p>To answer that question, here&#8217;s a <a
href="https://github.com/akosma/DelegateOrder">small project in
Github</a> that uses all the
delegate and datasource methods in the same project, and that uses NSLog
to show which calls happen first, and when.</p><p><span
id="more-3364"></span></p><h2>Delegate Methods</h2><p>But first, a quick recap on delegate methods in Objective-C.</p><p>In many (if not most) object oriented toolkits, properties tend to be
used when setting up an object such as a table view, for instance in
.NET, as shown in this example from <a
href="http://support.microsoft.com/kb/307860">Microsoft</a></p><pre><code>&lt;%@ Page language="c#" %&gt;
&lt;%@ Import Namespace="System.Data" %&gt;
&lt;%@ Import Namespace="System.Data.SqlClient" %&gt;
&lt;script runat="server"&gt;
void Page_Load(Object sender, EventArgs e)
{
   SqlConnection cnn = new
       SqlConnection("server=(local);database=pubs;Integrated Security=SSPI");
   SqlDataAdapter da = new SqlDataAdapter("select * from authors", cnn);
   DataSet ds = new DataSet();
   da.Fill(ds, "authors");
   Repeater1.DataSource = ds.Tables["authors"];
   Repeater1.DataBind();
}
&lt;/script&gt;
&lt;html&gt;
&lt;body&gt;
   &lt;form id="WebForm2" method="post" runat="server"&gt;
      &lt;asp:Repeater id="Repeater1" runat="server"&gt;
         &lt;ItemTemplate&gt;
         &lt;%# DataBinder.Eval(Container.DataItem,"au_id") %&gt;&lt;br&gt;
         &lt;/ItemTemplate&gt;
      &lt;/asp:Repeater&gt;
   &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p>In the code above (a classic ASP.NET page) the <code>Repeater1</code> instance (of
the <code>Repeater</code> class, which is a view component) is &#8220;bound&#8221; (a classic
example of &#8220;databinding&#8221;) to an instance of a <code>DataSet</code>. In this case,
we just call the <code>.DataBind()</code> method on the repeater object, and the
view component is filled with the data inside.</p><p>The advantage of this approach is that it is simpler from the point of
view of the developer; a couple of lines of code are usually enough.
However, this design tends to break the MVC model, because it creates a
direct dependency between the model and the view component. This
coupling makes it hard to modify the model of the application without
breaking the view layer.</p><p>In Objective-C this pattern is seldom used. Instead, an object will opt
to let someone else do the job for them. That other object is known as
the <strong>delegate object</strong>, and the methods to be implemented (sometimes
optionally) are referred to as a protocol. In this model, there is a
controller object that acts as intermediate between the view and the
model, effectively creating a decoupled MVC architecture.</p><p>In Objective-C, an object tells the compiler that it implements a
protocol using this syntax:</p><pre><code>@interface MyAppDelegate : NSObject &lt;UIApplicationDelegate&gt;
@end
</code></pre><p>The inclusion of <code>&lt;UIApplicationDelegate&gt;</code> signals that this class
conforms to the UIApplicationDelegate protocol. Meanwhile, in
UIApplication.h, you will see this:</p><pre><code>@protocol UIApplicationDelegate &lt;NSObject&gt;
@optional
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
...
@end
</code></pre><p>Thus, MyAppDelegate.m may optionally respond to <code>-applicationDidFinishLaunching:</code> and <code>-application:didFinishLaunchingWithOptions:</code>. (In this particular case,
be aware that the former method is used by apps prior to iOS 3.0, and
that the latter method should now be used instead.)</p><h2>More about Delegates</h2><p>It is up to the class in question to determine when to call a delegate
method, and in what order. This order is of particular interest when it
comes to iOS Table Views. In fact, go ahead and press Cmd-Shift-O in
Xcode right now. Search for and open UITableView.h.</p><p>Look inside. There&#8217;s a lot to take in here! In fact, that&#8217;s a good idea
- take a moment to browse this header. (Go ahead. We&#8217;ll wait.) A Cocoa
developer can write apps and never look once inside these header files.
To borrow (abuse?) a classic Apple mantra, we code different. We want to
get our hands dirty and look inside at the engine &#8230; or at least as
much of it as possible. The instance variables are out of our reach, but
there are plenty of other things to take in.</p><p>UITableView is unusual in that it declares two protocols, whereas most
classes you come across will only declare one.</p><p>The UITableViewDelegate is responsible for mediating all table cell
display and behavior. A quick look at the protocol makes this abundantly
clear. There are methods covering custom display, variable height,
headers and footers, accessories, selection, editing, reordering, and
indentation.</p><pre><code>@protocol UITableViewDelegate &lt;NSObject, UIScrollViewDelegate&gt;
</code></pre><p>UITableViewDataSource represents the data model object. While it
supplies no information about appearance &#8212; of the cells or otherwise &#8211;
this doesn&#8217;t mean it avoids cells altogether. There are methods covering
cell view creation (and, more importantly, reuse), the number of
sections and rows, titles for headers and footers, index titles along
the right-hand side, plus cell editing, insertion, deletion, and moving.</p><p>In this protocol, two methods are required:</p><pre><code>- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
</code></pre><p>The rest are optional. That&#8217;s right, even -numberOfSectionsInTableView:, which you almost always see implemented like so:</p><pre><code>- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
</code></pre><p>However, the header tells us that the default value is 1 if this is not
implemented! If all you have is one section, save yourself some extra
coding and leave it out. Aren&#8217;t well-documented header files great?</p><p>Now there has to be some degree of bootstrapping involved with setting
up these delegates. This is accomplished via properties:</p><pre><code>@property (nonatomic,assign) id &lt;UITableViewDataSource&gt; dataSource;
@property (nonatomic,assign) id &lt;UITableViewDelegate&gt;   delegate;
</code></pre><p>&#8230; and usually set to self:</p><pre><code>// Set the table view and data source delegates:
myTableView.delegate = self;
myTableView.dataSource = self;
</code></pre><p>If you use a UITableViewController, this is done for you automagically,
in addition to several other niceties. (We heart UITableViewController.
Use it early. Use it often!)</p><h2>Delegate Method Call Order</h2><p>Great. So we have two delegate objects that can receive almost 30 method
calls combined. Not five. Not ten. Thirty. Helpful as the delegate
design pattern is, it&#8217;s easy to get confused knowing which method will
be called at which time. Thus, it can also be instructive to know what
order these methods are called.</p><p>You can probably guess a few of them right off the bat. For instance,
-tableView:numberOfSections: is likely called before
-tableView:numberOfRows:inSection:. It&#8217;s not always so clear cut,
though.</p><p>So <em>how do we trace Objective-C messages anyway?</em> One possibility is to
set up an Xcode breakpoint and declare this as an action (borrowed from <a
href="http://stackoverflow.com/questions/1029962/nsobjcmessageloggingenabled-with-iphone-3-0">StackOverflow</a>):</p><pre><code>while 1
printf "[%s %s]", (char *)object_getClassName($r0), (char *) $r1
c
end
</code></pre><p>Hmm &#8230; maybe not.</p><p>Is it possible to trace Objective-C messages en masse? As a matter of
fact, <a
href="http://www.dribin.org/dave/blog/archives/2006/04/22/tracing_objc/">it is</a>:</p><p>On the iPhone Simulator, you can compile with the <code>NSObjCMessageLoggingEnabled</code> Foundation environment variable set to
YES, then look in <code>/tmp/msgSends-&lt;pid&gt;</code> (where <pid> is your running
app&#8217;s process id).</pid></p><p>You&#8217;ll also get a deluge of messages, accent on deluge.</p><p>What else? You could use (<a
href="http://developer.apple.com/technotes/tn2004/tn2124.html">the undocumented</a>) <code>-instrumentObjcMessageSends:</code> to toggle logging on and off.</p><p>Hmm. This isn&#8217;t looking so good. &#8220;There&#8217;s got to be a better way!&#8221;</p><p>We can certainly drop breakpoints in each of our delegate methods and
trace through them, but wouldn&#8217;t it be nice to just log the call order
of our class delegates in one swell foop, without resorting to
undocumented or cumbersome means?</p><h2>Using an NSProxy</h2><p>Of course there is. That&#8217;s why we wrote this blog post, after all, so
we&#8217;re going to show you how it&#8217;s done. Best of all, you can use this
technique for any class. Roll up your sleeves and let&#8217;s get started.</p><p>[This code is adapted from
http://blog.jayway.com/2009/03/06/proxy-based-aop-for-cocoa-touch/]</p><p>Remember, we&#8217;re operating under the notion that you know your way around
Xcode and have already built a project or two! In Xcode, create a new
&#8220;Master-Detail&#8221; iOS Application called DelegateOrder. We&#8217;re going to use
a PTV prefix for all of our classes (why? Long story <img
src='http://akosma.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Thanks to the wonders of modern template technology, our root view
controller happens to be a table view. How convenient!</p><p>Time to create a new class. Right-click on the Classes group in Xcode,
and choose New File&#8230; from the popup menu. Add an Objective-C Cocoa
Touch subclass of NSObject, and name it PTVControllerProxy. Open
PTVControllerProxy.h and change it to look like this:</p><pre><code>@interface PTVControllerProxy : NSProxy
+ (id&lt;UITableViewDataSource, UITableViewDelegate&gt;)proxyWithTableViewController:(UITableViewController *)controller;
- (id)initWithTableViewController:(UITableViewController *)controller;
@end
</code></pre><p>Notice anything different?</p><p>We have not so secretly replaced the NSObject Xcode usually serves with
a dark, sparkling NSProxy object. (Footnote: This is a cultural
reference to a famous Folgers coffee commercial that ran in the US in
the &#8217;80s. Not sure if it aired worldwide though!) Like NSObject, NSProxy
is a root class, except it also <em>conforms</em> to NSObject, plus it adds a
few methods of its own. Here&#8217;s the header:</p><pre><code>#import &lt;Foundation/NSObject.h&gt;
@class NSMethodSignature, NSInvocation;
@interface NSProxy &lt;NSObject&gt; {
    Class   isa;
}
+ (id)alloc;
+ (id)allocWithZone:(NSZone *)zone;
+ (Class)class;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
- (void)dealloc;
- (void)finalize;
- (NSString *)description;
+ (BOOL)respondsToSelector:(SEL)aSelector;
@end
</code></pre><p>NSProxy objects act as stand-ins for other objects. In our case, we&#8217;ll
use PTVControllerProxy as our table view&#8217;s dataSource and delegate. It
will also know about our actual Table View Controller (and table view)
so that it can pass messages down the line.</p><p>The next item of interest is our private instance variable, _controller,
a pointer to a UITableViewController object.</p><p>Following the Coding Guidelines for Cocoa, we always make our instance
variables private. We also add a leading underscore &#8212; just like Apple
does with their own headers &#8212; so as to distinguish them from
properties. This further enforces class interaction through properties
and methods. Meanwhile, on the implementation side, sometimes you want
to access the instance variable. Other times, you need to use the
property. Underscores make it clear which is which.</p><p>In this case, we&#8217;re not creating a property &#8230; at least not one that&#8217;s
publicly available. More on that later.</p><p>We&#8217;ve also defined one class method and one instance method:</p><pre><code>+ (id&lt;UITableViewDataSource, UITableViewDelegate&gt;)proxyWithTableViewController:(UITableViewController *)controller;
</code></pre><p>Our class method takes a UITableViewController and returns an object
that conforms to both the Table View Data Source and Delegate protocols.</p><pre><code>- (id)initWithTableViewController:(UITableViewController *)controller;
</code></pre><p>Our designated initializer method (called by the class method) does the
deed of setting our controller property.</p><p>Did we mean _controller instance variable? No, we meant property. Now
press Cmd-Option-Up-Arrow to switch to the implementation file and make
it look like this:</p><pre><code>#import "PTVControllerProxy.h"
@interface PTVControllerProxy ()
@property (nonatomic, assign) UITableViewController *controller;
- (void)logInvocation:(NSInvocation *)invocation;
@end
@implementation PTVControllerProxy
@synthesize controller = _controller;
@end
</code></pre><p>Ah-ha! So that&#8217;s where the property went.</p><p>We have included yet another interface declaration for
PTVControllerProxy, and this time we&#8217;re extending it beyond what we
originally declared in the header. The parentheses after @interface
PTVControllerProxy signify that this is a class extension. In this case,
we&#8217;ve declared a property and a method that isn&#8217;t exposed to the outside
world. It&#8217;s not private per se, but it&#8217;s not visible in the header
either. Next, in the implementation, we&#8217;ve synthesized a property named
controller, which is represented by the instance variable named
_controller.</p><p>Due to the architecture of Objective-C, you could make a few end-runs
around this and still get at the property and methods. You just have to
know how they&#8217;re defined. Be careful of doing this with Apple&#8217;s classes
though. Them&#8217;s grounds for App Store rejection!</p><p>You can even override extensions previously defined in the header,
making this technique quite handy for exposing readwrite properties as
readonly. Read more about Categories and Extensions in The Objective-C
Programming Language.</p><p>We&#8217;ll discuss <code>-logInvocation:</code> in a moment, but you probably have a
good idea of what it will do just by looking at the name.</p><p>Time to add our methods. Heads up: Some of these may &#8212; or will &#8212; be a
bit unfamiliar. All we are doing here is implementing the minimum number
of methods to handle proxying for our table view controller, and then
some.</p><p>The following should be added between @synthesize and @end in our class
implementation. First, we add our previously defined initializers, and
our lone NSObject method:</p><pre><code>#pragma mark - Initializers
+ (id&lt;UITableViewDataSource, UITableViewDelegate&gt;)proxyWithTableViewController:(UITableViewController *)controller
{
    return [[[[self class] alloc] initWithTableViewController:controller] autorelease];
}
- (id)initWithTableViewController:(UITableViewController *)controller
{
    self.controller = controller;
    return self;
}
#pragma mark - NSObject
- (void)dealloc
{
    [_controller release];
    [super dealloc];
}
</code></pre><p>Our class method takes a table view controller and sends it along to the
designated initializer, which in turn assigns it to the property
controller, and returns itself. As there is no superclass to worry
about, there is no use of <code>[super init]</code> here.</p><p>There&#8217;s one more benefit to our use of private instance variables
beginning with underscores. Our method parameters do not conflict with
like-named instance variables! Look at this line again:</p><pre><code>self.controller = controller;
</code></pre><p>This dot notation is 100% equivalent to:</p><pre><code>[self setController:controller];
</code></pre><p>Very clean, consistent, and easy to read. Contrast this with the
scenario where our instance and method variable named matched. We would
have to code methods like this:</p><pre><code>- (id)initWithTableViewController:(UITableViewController *)theController
{
    self.controller = theController;
    return self;
}
</code></pre><p>It should also be pointed out that these method names are not haphazard.
Apple does in fact provide a method (pun intended) for naming methods!
The previously mentioned Coding Guidelines for Cocoa tells all. Take the
time to name your instance variables, properties, and methods according
to the guidelines. It&#8217;s worth the effort!</p><p>The dealloc method is also standard-issue. Notice that we work with the
instance variable at this point. After dealloc, the show&#8217;s over for this
class, so we don&#8217;t even bother setting _controller to nil. In other
cases, you would likely want to clear it, using the property to take
advantage of its retain/release smarts in one step:</p><pre><code>// This setter (-setController:) releases _controller for us!
self.controller = nil;
</code></pre><p>Continuing with our NSObject methods, add the following:</p><pre><code>- (BOOL)isKindOfClass:(Class)aClass;
{
    return [self.controller isKindOfClass:aClass];
}
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
{
    return [self.controller conformsToProtocol:aProtocol];
}
- (BOOL)respondsToSelector:(SEL)aSelector;
{
    return [self.controller respondsToSelector:aSelector];
}
</code></pre><p>Be careful here. There are class methods with the same signature like
NSProxy&#8217;s +respondsToSelector:! We&#8217;re responding to NSObject&#8217;s protocol
methods instead, passing (well, proxying) the parameter over to our
table view controller. This takes care of establishing our proxy as
having the same class, protocol conformance, and selector response.
That, in turn, assures us an opportunity to tap in to the deluge of
table view delegate traffic.</p><p>Now, so we just discussed how you can avoid naming collisions between
method parameters and instance variables, and here we have aClass,
aProtocol, and aSelector! This leads us to an important maxim: &#8220;You have
to know the rules before you can break them.&#8221; Use discretion! Here,
we&#8217;re honoring the naming convention established by the authors of
NSObject.h, in particular the NSObject protocol.</p><p>As it turns out, the Protocol and Base Class declarations of <code>-conformsToProtocol:</code> are ever so slightly different:</p><pre><code>// Protocol
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
// Base Class
+ (BOOL)conformsToProtocol:(Protocol *)protocol;
</code></pre><p>Go figure. (It&#8217;s OK. We still love Cocoa. Tasty Cocoa &#8230;)</p><p>Let&#8217;s add two more, slightly longer methods, this time from NSProxy&#8217;s
protocol:</p><pre><code>#pragma mark - NSProxy
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    if ([self.controller respondsToSelector:aSelector])
    {
        return [self.controller methodSignatureForSelector:aSelector];
    }
    else
    {
        return [super methodSignatureForSelector:aSelector];
    }
}
</code></pre><p>Method signatures help us forward along messages we otherwise wouldn&#8217;t
respond to. Here, the message is either bound for our table view
controller or the superclass.</p><pre><code>- (void)forwardInvocation:(NSInvocation *)invocation
{
    SEL selector = [invocation selector];
    if ([self.controller respondsToSelector:selector])
    {
        [self logInvocation:invocation];
        [invocation setTarget:self.controller];
        [invocation invoke];
    }
}
</code></pre><p><code>-forwardInvocation:</code> is used by subclasses to send Objective-C
messages-as-objects (or Invocations) to other objects. For the proxy,
it&#8217;s just a matter of passing the message along to whatever object we
aim to represent. That object, of course, is the table view controller.</p><p>First, we ensure the controller responses to the selector represented by
the invocation. Then, just before we dispatch the invocation using
-invoke, we call &#8211; ta-dah &#8211; our private -loginvocation: method. With
that, we can now log every single solitary table view controller message
that comes our way, all from one place.</p><p>Oh, and look, it&#8217;s invocation and not anInvocation. (You&#8217;re not going to
let us live this one down, are you.)</p><p>At last, we come to the coup de grace of our controller proxy class. Add
this to the implementation:</p><pre><code>#pragma mark - Private
- (void)logInvocation:(NSInvocation *)invocation
{
    SEL selector = [invocation selector];
    NSString *currentMethod = NSStringFromSelector(selector);
    NSString *argument = @"";
    NSMethodSignature *methodSignature = [invocation methodSignature];
    NSInteger argCount = [methodSignature numberOfArguments];
    for (NSInteger index = 3; index &lt; argCount; ++index)
    {
        const char *argType = [methodSignature getArgumentTypeAtIndex:index];
        if (strcmp(argType, "@") == 0)
        {
            id object = nil;
            [invocation getArgument:&amp;object atIndex:index];
            if ([object isKindOfClass:[NSIndexPath class]])
            {
                NSIndexPath *indexPath = (NSIndexPath *)object;
                argument = [NSString stringWithFormat:@"{%d, %d}", indexPath.section, indexPath.row];
            }
        }
        else if (strcmp(argType, "i") == 0)
        {
            NSInteger section;
            [invocation getArgument:&amp;section atIndex:index];
            argument = [NSString stringWithFormat:@"%d", section];
        }
    }
    NSLog(@"%@%@", currentMethod, argument);
}
</code></pre><p>OK! A lot to take in here. Let&#8217;s talk through it.</p><p>Just like in <code>-forwardInvocation:</code>, we grab our selector, or in this case
our delegate message. In preparation for logging, we turn it into a
string called <code>currentMethod</code>. This gives us, for example,
@&#8221;tableView:cellForRowAtIndexPath:&#8221; &#8211; ready for logging.</p><p>Perhaps that would be enough, but we can do better. NSInvocation
contains a NSMethodSignature object with all the arguments, so let&#8217;s
grab a few of those while we&#8217;re at it.</p><p>If you were to look at the method signature&#8217;s arguments, you would soon
discover the first two arguments are always claimed by a few
behind-the-scenes players, (id)self and (SEL)_cmd. Argument indices are
zero-based, so that places us at index 2 for the start of our delegate
methods. Meanwhile, following best practices for delegate method
conventions, the table view is always passed back as the first argument,
in this case index 2. Thus we want to start at index 3, which should
explain this loop construct:</p><pre><code>for (NSInteger index = 3; index &lt; argCount; ++index)
{
    const char *argType = [methodSignature getArgumentTypeAtIndex:index];
...
</code></pre><p>Next, we look at the argument type, returned as constant C string
representing an Objective C argument type. &#8220;@&#8221; represents an object, and
&#8220;i&#8221; represents an integer. Easy enough.</p><p>If we have an object, we check to see if it&#8217;s of class NSIndexPath. If
so, good! We grab the index path&#8217;s row and section, and use that in the
log message. If we have an integer, we simply grab the integer value
instead.</p><p>What if we have no such argument, as in -numberOfSectionsInTableView? No
worries, we&#8217;ll still log the message. We just won&#8217;t have any of these
parameters to go along with it.</p><p>Finally, we log our method and our (possible) lone argument. At last,
the controller proxy is complete.</p><p>We now turn our attention to our table view controller, represented here
by PTVRootViewController. Open the header file first, and change it to
look like this:</p><pre><code>#import &lt;UIKit/UIKit.h&gt;
@interface PTVRootViewController : UITableViewController
{
@private
    id&lt;UITableViewDataSource, UITableViewDelegate&gt; _proxy;
}
@end
</code></pre><p>We&#8217;ve merely added a private instance variable for the proxy object.
Notice that there is no publicly exposed property. We will only be using
the proxy within the confines of the class.</p><p>Now switch to the implementation file and &#8230; remove everything. Nothing
wrong with the pre-fab code here. We&#8217;re just going to start over. Add
this for starters:</p><pre><code>#import "PTVRootViewController.h"
#import "PTVControllerProxy.h"
static NSInteger SECTION_COUNT = 25;
static NSInteger ROW_COUNT = 5;
</code></pre><p>We first import our class header, as well as the proxy header. Next,
because we&#8217;re testing out the proxy, we can keep the data source rather
sparse and simple, but we still want a good number of rows and sections
to work with. We define a few constants to this effect, giving us 25
table view sections, each one with five rows.</p><p>Time for another private extension:</p><pre><code>@interface PTVRootViewController ()
@property (nonatomic, retain) id&lt;UITableViewDataSource, UITableViewDelegate&gt; proxy;
@end
@implementation PTVRootViewController
@synthesize proxy = _proxy;
@end
</code></pre><p>There it is, our internal proxy property, and a bare-bones
implementation, complete with synthesized methods. Next up is our
requisite NSObject method:</p><pre><code>#pragma mark - NSObject
- (void)dealloc
{
    [_proxy release];
    [super dealloc];
}
</code></pre><p>Nothing earth-shattering there. Next up, a bunch of UIViewController
methods:</p><pre><code>#pragma mark - UIViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.proxy = [PTVControllerProxy proxyWithTableViewController:self];
    self.tableView.dataSource = self.proxy;
    self.tableView.delegate = self.proxy;
    self.title = @"Delegate Call Order";
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
</code></pre><p>In -viewDidLoad, we create and connect the proxy object. We also take a
moment to set the associated navigation bar&#8217;s title and add a stock edit
button on the right side.</p><pre><code>- (void)viewDidUnload
{
}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
</code></pre><p>We&#8217;ll disable autorotation for now, so we only respond to portrait
orientation requests.</p><pre><code>- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
</code></pre><p>At last! Time to add the delegate methods. <em>All of them</em>. That&#8217;s right, <strong>we will respond to every single one</strong>. In doing so, the proxy will get
a chance to work its logging magic. Add the following for starters:</p><pre><code>#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return SECTION_COUNT;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:SECTION_COUNT];
    for (NSInteger index = 0; index &lt; SECTION_COUNT; ++index)
    {
        NSString *sectionTitle = [NSString stringWithFormat:@"%d", index];
        [array addObject:sectionTitle];
    }
    return array;
}
</code></pre><p>Our table view has <code>SECTION_COUNT</code> sections. The section index titles
(along the right side of the table view) will be represented by our
section numbers 0 through 24. This will make it easy to see the effects
of changing our vantage point.</p><p>Let&#8217;s add a few more:</p><pre><code>- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
</code></pre><p>We allow editing and moving of all rows.</p><pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"Section %d, row %d", indexPath.section, indexPath.row];
    return cell;
}
</code></pre><p>Here is where the cell generation and reuse takes place. Again, nothing
surprising here. We take advantage of our table view&#8217;s cell queue and
either dequeue or create a cell, setting its text label to the current
cell&#8217;s section and row.</p><pre><code>- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
    else if (editingStyle == UITableViewCellEditingStyleInsert)
    {
    }
}
</code></pre><p>Since we&#8217;re allowing editing (and by editing we mean deletion of cells,
not insertion), we&#8217;ll respond to this method as well, deleting the row
indicated by the indexPath, fading it out as it goes.</p><pre><code>- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return ROW_COUNT;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [title intValue];
}
</code></pre><p>We respond to <code>-tableView:moveRowAtIndexPath:toIndexPath:</code> as well.
Since we aren&#8217;t manipulating any behind-the-scenes data, we don&#8217;t need
to do anything extra. We also offer up <code>ROW_COUNT</code> rows in each section.
Next, we take advantage of our section index titles (which are just
numbers represented as strings), converting them back to integers as
needed.  index is meant to be used with our index title array, which of
course we aren&#8217;t keeping track of. Then again, it&#8217;s simple enough that
we don&#8217;t have to. Each index title maps directly to a like-numbered
section in the table view, so it&#8217;s as simple as returning each title&#8217;s
integer value.</p><p>Two more data source methods and we&#8217;re more than halfway there.</p><pre><code>- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
    return [NSString stringWithFormat:@"Footer for section %d", section];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [NSString stringWithFormat:@"Header for section %d", section];
}
</code></pre><p>Easy peasy, right? Good! Now for the table view delegate methods. These
are even easier:</p><pre><code>#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}
</code></pre><p>A few more empty methods, again just to get the benefit of logging. We
will also deselect each row in response to it being selected. Next, we
assure that the editing style of each row supports deletion.</p><p>Now we&#8217;ll handle header, footer, and row sizing, plus indentation:</p><pre><code>- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 20.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 20.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44.0f;
}
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 0;
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
</code></pre><p>Returning YES for <code>-tableView:shouldIndentWhileEditingRowAtIndexPath:</code> allows the background of the edited row to be indented. This allows the
cell contents to shift and more gracefully accomodate the Delete button
appearing on the right-hand side.</p><pre><code>- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    return proposedDestinationIndexPath;
}
</code></pre><p>We won&#8217;t do anything unusual with proposed moving of cells, so we return
the proposed destination index path.</p><pre><code>- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"Delete";
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return nil;
}
</code></pre><p>The delete confirmation button will remain @&#8221;Delete&#8221;, and we won&#8217;t be
using views for the section headers or footers. Still, we need to
implement these methods if we are to see them logged!</p><p>Four more methods to go, and our implementation is finished:</p><pre><code>- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    return indexPath;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    return indexPath;
}
</code></pre><h2>Executing the Code</h2><p><img
src="http://akosma.com/wp/wp-content/uploads/2012/01/delegateorder1.png" alt="Delegateorder1" border="0" width="170" height="319" class="alignleft size-full" /></p><p>Congratulations! Let&#8217;s take it for a spin in the Simulator. Before
building your project, bring up the debugger console window by typing
Shift-Cmd-R or selecting Run > Console from the menu. Move the console
off to the side so that you can see what happens next. You might even
want to venture a guess as to which messages and parameters you&#8217;ll see
first. Place your bets!</p><p>Now Build and Run your project using the Debug configuration. The
Simulator will launch and the console will soon be filled with a bunch
of log messages. Do not use the Simulator just yet. Let&#8217;s focus on the
console.</p><p>Thankfully, they will only be concerning our table view controller
delegates. (Otherwise, we would be positively buried with messages. You
think <em>this</em> is a lot of messages, you should see what Objective-C deals
with in a typical app&#8217;s lifetime!)</p><p>Let&#8217;s start at the top and see what we have here. (We have removed the
timestamp and App specific info. Your log lines will be a bit lengthier
by comparison. You might want to make the console window a bit wider to
help keep the lines from wrapping.)</p><pre><code>numberOfSectionsInTableView:
numberOfSectionsInTableView:
</code></pre><p>The first thing we&#8217;re asked for is the number of sections in our table
view &#8230; and we&#8217;re asked for this information <em>twice</em>. (Your guess is as
good as ours.)</p><p>Remember, we have 24 sections in our table view.</p><pre><code>tableView:viewForHeaderInSection:24
tableView:titleForHeaderInSection:24
tableView:heightForHeaderInSection:24
tableView:heightForHeaderInSection:24
tableView:viewForFooterInSection:24
tableView:titleForFooterInSection:24
tableView:heightForFooterInSection:24
tableView:heightForFooterInSection:24
</code></pre><p>Next, we see a bunch of messages pertaining to one section, in this case
section 24. First the headers, then the footers. Here we have two more
examples of a twice-called method in <code>-tableView:heightForHeaderInSection:</code> and <code>-tableView:heightForFooterInSection:</code>.</p><p>So the order so far is as follows (eliminating duplicate invocations):</p><pre><code>numberOfSectionsInTableView:
</code></pre><p>Then, for each section, the header and footer information:</p><pre><code>tableView:viewForHeaderInSection:
tableView:titleForHeaderInSection:
tableView:heightForHeaderInSection:
tableView:viewForFooterInSection:
tableView:titleForFooterInSection:
tableView:heightForFooterInSection:
</code></pre><p>You can imagine that the title is not needed (and the relevant method
not called) if a view is returned, so it makes sense that the view is
asked for first.</p><p>Armed with our section count, the table view turns its attention to the
rows, starting with &#8230; the last one?</p><pre><code>tableView:numberOfRowsInSection:24
tableView:heightForRowAtIndexPath:{24, 0}
tableView:heightForRowAtIndexPath:{24, 1}
tableView:heightForRowAtIndexPath:{24, 2}
tableView:heightForRowAtIndexPath:{24, 3}
tableView:heightForRowAtIndexPath:{24, 4}
</code></pre><p>We have 5 rows in each section, which explains the index paths from {24,
0} through {24, 4}. The height is returned for each. So far, so good.</p><p>Now it would appear as if we&#8217;re starting at the end of the list and
working our way backward, but the next thing you see is this:</p><pre><code>tableView:viewForHeaderInSection:0
tableView:titleForHeaderInSection:0
tableView:heightForHeaderInSection:0
tableView:heightForHeaderInSection:0
tableView:viewForFooterInSection:0
tableView:titleForFooterInSection:0
tableView:heightForFooterInSection:0
tableView:heightForFooterInSection:0
tableView:numberOfRowsInSection:0
tableView:heightForRowAtIndexPath:{0, 0}
tableView:heightForRowAtIndexPath:{0, 1}
tableView:heightForRowAtIndexPath:{0, 2}
tableView:heightForRowAtIndexPath:{0, 3}
tableView:heightForRowAtIndexPath:{0, 4}
</code></pre><p>Is UITableView darting back and forth between the beginning and the end?
(Answer: No. The next section it inquires about is section 1, all the
way up to 23.) In fact, if you recompile this with only three sections,
numbered 0 through 2, you&#8217;ll get a similar outcome with the section
order: 2, 0, and 1.</p><p>So what&#8217;s happening here? Why does UITableView need to know about the
last section first? [Note: Unknown! Any insights?]</p><pre><code>sectionIndexTitlesForTableView:
</code></pre><p>Now that UITableView knows all the row heights, you shouldn&#8217;t see those
called again unless the table is reloaded. That&#8217;s a good thing too
because calculating those row heights can take some time, depending on
the situation.</p><pre><code>tableView:cellForRowAtIndexPath:{0, 0}
tableView:indentationLevelForRowAtIndexPath:{0, 0}
tableView:canEditRowAtIndexPath:{0, 0}
tableView:willDisplayCell:forRowAtIndexPath:{0, 0}
</code></pre><p>Next up are a series of four messages for each visible row, as well as
those just out of view above and below. Since we&#8217;re at the start of the
content area, we begin with index path {0, 0} and the messages are sent
all the way through index path <code>{1, 3}</code>. The familiar <code>-tableView:cellForRowAtIndexPath:</code> is called first, followed by a
request for the indentation level, and a check to see if the row is
editable.  Last comes <code>-tableView:willDisplayCell:forRowAtIndexPath:</code>.
If you&#8217;ve read the documentation, you know this is your last chance to
make final adjustments before a cell is displayed &#8230; and now we have
proof!</p><pre><code>tableView:viewForHeaderInSection:0
tableView:titleForHeaderInSection:0
tableView:viewForFooterInSection:0
tableView:titleForFooterInSection:0
</code></pre><p>Finally, we have a set of four different messages for the view (or,
failing that, the title) for the header in each visible section. You
probably know that headers are always visible, even when all of a given
section&#8217;s rows are not. This holds true for section footers as well,
only these are kept visible on the bottom of the view instead of the
top.</p><p>In the Debugger console, press return a few times to add some blank
space (or just press Clear Log in the toolbar). Now let&#8217;s try and scroll
another screenful of rows into view and see what happens. Click and drag
the bottom-most row up to the top until Section 2, row 4 is visible.
Here&#8217;s what we get. Note that we have added blank lines in between each
logical group of method invocations.</p><pre><code>tableView:viewForHeaderInSection:0
tableView:titleForHeaderInSection:0
tableView:cellForRowAtIndexPath:{1, 4}
tableView:indentationLevelForRowAtIndexPath:{1, 4}
tableView:canEditRowAtIndexPath:{1, 4}
tableView:willDisplayCell:forRowAtIndexPath:{1, 4}
tableView:viewForFooterInSection:1
tableView:titleForFooterInSection:1
tableView:viewForHeaderInSection:2
tableView:titleForHeaderInSection:2
tableView:cellForRowAtIndexPath:{2, 0}
tableView:indentationLevelForRowAtIndexPath:{2, 0}
tableView:canEditRowAtIndexPath:{2, 0}
tableView:willDisplayCell:forRowAtIndexPath:{2, 0}
tableView:viewForFooterInSection:2
tableView:titleForFooterInSection:2
tableView:cellForRowAtIndexPath:{2, 1}
tableView:indentationLevelForRowAtIndexPath:{2, 1}
tableView:canEditRowAtIndexPath:{2, 1}
tableView:willDisplayCell:forRowAtIndexPath:{2, 1}
tableView:cellForRowAtIndexPath:{2, 2}
tableView:indentationLevelForRowAtIndexPath:{2, 2}
tableView:canEditRowAtIndexPath:{2, 2}
tableView:willDisplayCell:forRowAtIndexPath:{2, 2}
tableView:cellForRowAtIndexPath:{2, 3}
tableView:indentationLevelForRowAtIndexPath:{2, 3}
tableView:canEditRowAtIndexPath:{2, 3}
tableView:willDisplayCell:forRowAtIndexPath:{2, 3}
tableView:viewForHeaderInSection:1
tableView:titleForHeaderInSection:1
tableView:cellForRowAtIndexPath:{2, 4}
tableView:indentationLevelForRowAtIndexPath:{2, 4}
tableView:canEditRowAtIndexPath:{2, 4}
tableView:willDisplayCell:forRowAtIndexPath:{2, 4}
</code></pre><p><img
src="http://akosma.com/wp/wp-content/uploads/2012/01/delegateorder2.png" alt="Delegateorder2" border="0" width="600" height="409" class="alignleft size-full" /></p><p>Of particular interest here are the header and footer related methods.
They appear to be invoked in a rather odd pattern, until you examine the
order that each header and footer appears on screen. Then it makes
perfect sense. Interestingly enough, now that we&#8217;re on the move and have
stopped at a definitive spot, we never see index path {3, 0} on the
radar, which is just out of view, past the bottom.</p><p>What about editing? Add some blank space in your debugger, then tap the
edit button.</p><pre><code>tableView:canEditRowAtIndexPath:{1, 1}
tableView:editingStyleForRowAtIndexPath:{1, 1}
tableView:shouldIndentWhileEditingRowAtIndexPath:{1, 1}
tableView:canMoveRowAtIndexPath:{1, 1}
</code></pre><p>We&#8217;ve already seen -tableView:canEditRowAtIndexPath: invoked, just
before our last chance to adjust the cell prior to display. Now it&#8217;s the
first message in the group, followed by a few additional requests. The
editing style is sought, followed by a request to indent the row while
editing, and rounded out by an inquiry to see if the row can be moved.</p><p>Here&#8217;s another observation. Notice how index path {1, 1} seems to be out
of view in our example, yet we see it being called here. This is
repeated through index path {2, 4} which is just in view, but <em>not</em> index path {3, 0} which is just out of view once again. Why?</p><p>There is a good reason for this behavior. When a header and footer are
covering up rows within their related section (that is, when the header
or footer is pegged to the top or bottom of the visible part of the
view), look for a little bit of transparency, letting the underlying
cells show through. When a header is directly above the first cell in
its section (or when a footer is directly below the last cell in its
section), there are no underlying cells to show through. In our case, we
know each section has a header and footer. Thus, there is no need for
fetching adjacent section/row data until at least the next section&#8217;s
header comes into view.</p><p>Let&#8217;s switch Section 1, rows 3 and 4. With the debugger console in view,
tap and hold index path {1, 4}, just over the three bars (signifying a
movable row). Drag it upward until it switches places with index path
{1, 3} but don&#8217;t let go just. Observe the log:</p><pre><code>tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:{1, 3}
</code></pre><p>Had we been logging this one more completely, it would have looked like this:</p><pre><code>tableView:targetIndexPathForMoveFromRowAtIndexPath:{1, 4}toProposedIndexPath:{1, 3}
</code></pre><p>That&#8217;s all the table view needs to do. Now let go, and the move is complete:</p><pre><code>tableView:moveRowAtIndexPath:toIndexPath:{1, 3}
</code></pre><p>Again, a more complete log would have shown:</p><pre><code>tableView:moveRowAtIndexPath:{1, 4}toIndexPath:{1, 3}
</code></pre><p>Tap Done in the navigation bar, and we see this:</p><pre><code>tableView:canEditRowAtIndexPath:{1, 1}
tableView:canEditRowAtIndexPath:{1, 2}
tableView:canEditRowAtIndexPath:{1, 3}
tableView:canEditRowAtIndexPath:{1, 4}
tableView:canEditRowAtIndexPath:{2, 0}
tableView:canEditRowAtIndexPath:{2, 1}
tableView:canEditRowAtIndexPath:{2, 2}
tableView:canEditRowAtIndexPath:{2, 3}
tableView:canEditRowAtIndexPath:{2, 4}
</code></pre><p>Terrific! Now what other mischief can we cause? Let&#8217;s delete section 2,
row 1 (index path {2, 1}). Add some whitespace to the console, then tap
edit once again, then the red circle at the left of the cell in section
2, row 1.</p><pre><code>tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:{2, 1}
</code></pre><p>Makes sense. The delete button appears (properly labeled). Now tap it to
delete the row.</p><pre><code>tableView:commitEditingStyle:forRowAtIndexPath:{2, 1}
</code></pre><p>First, we commit the editing style for index path {2, 1}. Then we
effectively have a <code>reloadData</code> operation, which causes everything to be
rechecked once again &#8211; headers, footers, row heights, the works. Only
now we start at index path {0, 0} and run all the way clear through {24,
4}. So section 24 gets to go last this time!</p><p>Aaaand &#8230; the app crashes big-time.</p><pre><code> *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1261.5/UITableView.m:920
 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 2.  The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'
</code></pre><p>Wha happen? Well, our faux data model still thinks there are 24 sections
of five rows each. Obviously that doesn&#8217;t match up with the table view&#8217;s
reality. In short, &#8220;table view fall down go boom.&#8221;</p><p>Well, it was fun while it lasted <img
src='http://akosma.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Get the <a
href="https://github.com/akosma/DelegateOrder">whole source code on
Github</a> and we hope it&#8217;ll be useful to you!</p><p><strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2011/03/28/smart-pointers-in-objective-c/" rel="bookmark" title="March 28, 2011">Smart Pointers in Objective-C++</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/" rel="bookmark" title="October 11, 2010">How knowing C and C++ can help you write better iPhone apps, part 1</a></li><li><a
href="http://akosma.com/2010/07/17/nib2objc-updated/" rel="bookmark" title="July 17, 2010">nib2objc updated</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>A Proposed Architecture for Network-Bound iOS Apps</title><link>http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/</link> <comments>http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/#comments</comments> <pubDate>Tue, 20 Sep 2011 15:48:17 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[application]]></category> <category><![CDATA[Architecture]]></category> <category><![CDATA[blocks]]></category> <category><![CDATA[delegates]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[Network]]></category> <category><![CDATA[notifications]]></category> <category><![CDATA[polymorphism]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3094</guid> <description><![CDATA[One of my most popular answers in StackOverflow is the one I gave to the following question: &#8220;What is the best architecture for an iOS application that makes many network requests?&#8221; The problem is the following: let&#8217;s consider a relatively complex application, which has to connect to, and retrieve and send data from different remote [...]]]></description> <content:encoded><![CDATA[<p>One of my <a
href="http://stackoverflow.com/questions/4810289/best-architecture-for-an-ios-application-that-makes-many-network-requests/4823001#4823001">most popular
answers</a> in StackOverflow is the one I gave to the following question: &#8220;What is
the best architecture for an iOS application that makes many network
requests?&#8221;</p><p>The problem is the following: let&#8217;s consider a relatively complex
application, which has to connect to, and retrieve and send data from
different remote resources (from the same origin or from different
ones), all while handling as gracefully as possible different problems
such as &#8220;network not available&#8221;, &#8220;500&#8243; errors, etc, while at the same
time notifying the app about showing popups, enabling and disabling
fields, with many different screens (usually each with its own
controller), and so on.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/02/senbei_icon.png"
alt="senbei_icon.png" border="0" width="170" height="170"
class="alignleft size-full" /></p><p>This article will describe in detail a solution for this problem using <a
href="http://allseeing-i.com/ASIHTTPRequest/">ASIHTTPRequest</a>, my favorite
HTTP library for iOS. The solution involves a bit of object oriented
code, and there is a sample implementation in our <a
href="https://github.com/akosmasoftware/Senbei/">Senbei project in
Github</a> that I am going to
refer to in this article.</p><p>I want to point out that I do not consider this the &#8220;best&#8221; architecture
by any means; it is simply a pattern or structure that has given me
excellent results in many different applications, and which has evolved
over time from many other approaches. If someone else has a better idea,
I&#8217;d be glad to try it! This architecture also has the advantage of being
easy to document, understand, maintain and extend.<span
id="more-3094"></span>In the answer on StackOverflow I just enumerated the different elements
of the architecture; here I will explain the rationale behind every
decision.</p><h2>Singleton, &#8220;Class Cluster&#8221;</h2><p>As I said in the answer, this architecture involves a single object
taking care of network connectivity, which I will call a &#8220;network
manager&#8221;. Typically this object is a singleton (created using <a
href="http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html">Matt
Gallagher&#8217;s Cocoa singleton macro</a>). Basically this is because it&#8217;s a
good way to centralize all the network logic in a single component, and
it is also a very common Cocoa design pattern.</p><p>This object can also be seen as a class cluster, because it uses an army
of individual classes that perform the real work behind the scenes.</p><p>In Senbei, this singleton object is the <a
href="https://github.com/akosmasoftware/Senbei/tree/master/Classes/Helpers/SBNetworkManager">SBNetworkManager</a> class. All the
controllers of the application use the methods of this class to trigger
asynchronous requests to the remote FFCRM server used by the
application. All of these controllers, as well as the application
delegate, are notified of events by means of ad hoc notifications
(defined in the <a
href="https://github.com/akosmasoftware/Senbei/blob/master/Classes/Helpers/SBNotifications.h">SBNotifications.h</a> file).</p><h2>Network Queues</h2><p>The network manager wraps an instance of ASINetworkQueue, and also acts
as its delegate. Network queues are interesting in mobile apps, given
that the available bandwidth varies drastically when the device is
connected through a wifi connection or a low-speed GPRS mobile network.
The network queue will automatically change the number of requests sent
by unit of time depending on the current connectivity, without clogging
the device.</p><p>In our example, SBNetworkManager has a private ivar (well, as private as
Objective-C allows ivars to be) pointing to an instance of
ASINetworkQueue, itself a subclass of NSOperationQueue.</p><h2>One Subclass per Request</h2><p>I create subclasses of ASIHTTPRequest for each kind of network request
that my app requires (typically, for each backend REST interaction or
SOAP endpoint).</p><p>I also create a base class for all the requests of the application; this
allows to centralize some shared behavior in the base class, which
proves handy while extending and refactoring your network code.</p><p>In our example, Senbei has a base class for all the GET requests in the
application, called <a
href="https://github.com/akosmasoftware/Senbei/blob/master/Classes/Helpers/SBNetworkManager/Requests/SBBaseRequest.h">SBBaseRequest</a>. There is another base request, called <a
href="https://github.com/akosmasoftware/Senbei/blob/master/Classes/Helpers/SBNetworkManager/Requests/SBBaseFormDataRequest.h">SBBaseFormDataRequest</a>, which is used for requests that use the POST and
PUT verbs (used to create and modify resources on the server).</p><p>There is also a category on ASIHTTPRequest, to add some methods to any
request create on the system; this is required because SBBaseRequest
inherits from ASIHTTPRequest, while SBFormDataRequest inherits from
ASIHTTPFormDataRequest, which also inherits from ASIHTTPRequest. The
category on the latter allows to inject some common behavior in a way
that classic inheritance does not allow per se.</p><p>For every network interaction in the server, there is a dedicated class
available for the SBNetworkManager; the code is easy to understand, and
the responsibilities are separated and well defined. Should the system
be extended in the future, the extension mechanism will naturally fit
any new request, in a horizontal fashion.</p><p>The following class diagram (generated from the Xcode project using the
excellent [OmniGraffle][9] application) shows how the system is structured
(you can click the diagram to see a larger version).</p><p><a
href="http://akosma.com/wp/wp-content/uploads/2011/09/diagram-large.png"><img
src="http://akosma.com/wp/wp-content/uploads/2011/09/diagram.png" alt="Network manager class diagram" border="0" width="620" height="241" class="alignleft size-full" /></a></p><h2>Polymorphism to the Rescue</h2><p>The network manager doesn&#8217;t know what to do with the result of each
request; hence, it just calls a method <strong>on the request</strong>. Remember,
requests are subclasses of ASIHTTPRequest, so you can just put the code
that manages the result of the request (typically, deserialization of
JSON or XML into real objects, triggering other network connections,
updating Core Data stores, etc). Putting the code into each separate
request subclass, using a polymorphic method with a common name accross
request classes, makes it very easy to debug and manage them.</p><p>In our example, the SBNetworkManager calls the &#8220;processResponse&#8221; method
in each subclass. This method has an empty implementation in our
category for ASIHTTPRequest, and each individual subclass performs a
different set of operations; some will parse XML, some will just post a
notification; the separation of the logic in each subclass makes it easy
to debug, document, maintain and extend the system.</p><h2>Usage</h2><p>Every time one of my controllers requires some data (refresh,
viewDidAppear, etc), the network manager creates an instance of the
required ASIHTTPRequest subclass, and then adds it to the queue.</p><p>Whenever a request finishes or fails, the network manager is called
(remember, the network manager is the queue&#8217;s delegate). In turn, the
network manager calls a method on the request itself, delegating the
task of the processing of the response to each subclass.</p><p>In Senbei, every method of the SBNetworkManager class just creates an
instance of a dedicated SBBaseRequest subclass, and pushes it into the
wrapped network queue.</p><h2>Notifications</h2><p>The network manager notifies the controllers above about interesting
events using notifications; using a delegate protocol is not a good
idea, because in your app you typically have many controllers talking to
your network manager, and notifications are more flexible.</p><p>However, as with always with notifications, using them requires
planning, naming conventions and documentation. Code using notifications
might be complex to maintain, because the dependencies are not obvious
at first hand; that&#8217;s the price of their flexibility. In Senbei,
notifications are all defined in the same file, so that different
components can use the same constants throughout the application. The
names of the notifications are clear and express the purpose and
circumstance of each one.</p><p>Since iOS 4 there is also the possibility of using blocks as callback
notifications, but then again, I think they just offer an alternative to
delegate protocols; notifications are much more flexible, as many
different objects can be notified of the same event (and receive the
same information through userInfo dictionaries) at once.</p><h2>Conclusion</h2><p>This is how I&#8217;ve been writing many network-bound apps for the past few
years, and frankly it has worked pretty well so far. I can extend the
system horizontally, adding more ASIHTTPRequest subclasses as I need
them, and the core of the network manager stays intact. The
responsibilities is clearly separated, and the class and notification
names give a pretty good idea of the purpose of each request.</p><p>One problem that I haven&#8217;t yet solved with this architecture (and one
that a commenter of my StackOverflow answer points out) is finding a way
to test the system; probably using mock objects, we could simulate
different network conditions, and integrate this knowledge with
automated tests.</p><p>I hope that this architecture is useful to you too! I look forward to
read your comments below.</p><p>[9]:http://www.omnigroup.com/products/omnigraffle/<strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/09/27/senbei-1-3-hits-the-app-store/" rel="bookmark" title="September 27, 2011">Senbei 1.3 hits the App Store!</a></li><li><a
href="http://akosma.com/2010/05/28/initwithcontentsofurl-methods-considered-harmful/" rel="bookmark" title="May 28, 2010">initWithContentsOfURL: Methods Considered Harmful</a></li><li><a
href="http://akosma.com/2011/10/19/attending-senchacon-2011/" rel="bookmark" title="October 19, 2011">Attending SenchaCon 2011</a></li><li><a
href="http://akosma.com/2010/02/18/mobile-marketing-branding-seminar-in-zurich-save-15/" rel="bookmark" title="February 18, 2010">Mobile Marketing &#038; Branding Seminar in Zürich &#8211; Save 15%!</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Useful 3rd Party Extensions to CoreTextWrapper</title><link>http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/</link> <comments>http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/#comments</comments> <pubDate>Thu, 07 Jul 2011 09:10:12 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Open Source]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[collaboration]]></category> <category><![CDATA[contribution]]></category> <category><![CDATA[Core Text]]></category> <category><![CDATA[open source]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3015</guid> <description><![CDATA[Our CoreTextWrapper project in Github is certainly popular! Many developers have told us that they find it easier to approach Core Text using it, providing an easy learning path, showing the key concepts with an easy-to-use example. Some developers have gone the extra mile, though: we have kindly received two enhancements for the project! Jared [...]]]></description> <content:encoded><![CDATA[<p><a
target="_blank" href="https://github.com/akosma/CoreTextWrapper">Our CoreTextWrapper project in Github</a> is certainly popular! Many developers have told us that they find it easier to approach Core Text using it, providing an easy learning path, showing the key concepts with an easy-to-use example.</p><p>Some developers have gone the extra mile, though: we have kindly received two enhancements for the project!</p><ul><li><a
target="_blank" href="https://github.com/JaredCrawford">Jared Crawford</a> contributed support for shadows in AKOCustomFontLabel <a
target="_blank" href="https://github.com/akosma/CoreTextWrapper/commit/66af5409db46410e3cc8f5490ea9f4418e2843be">back in March.</a></li><li>Today, <a
target="_blank" href="http://www.tapwork.de/">Christian Menschel from tapwork.de</a> contributed the AKOMultiColumnTextViewDataSource protocol to add custom views in the text columns.</li></ul><p>These contributions make the CoreTextWrapper a very interesting option to display rich, multi-column text on your iPad application! Thanks to Jared and Christian for the contributions, and don&#8217;t hesitate to send us your pull requests or your changes for us to integrate with the project. We would love to make your code part of this project.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2011/07/coredatawrapper_view.png" alt="Coredatawrapper view" border="0" width="440" height="315" class="alignnone size-medium" /><strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2011/01/20/new-project-request-form/" rel="bookmark" title="January 20, 2011">New Project Request Form</a></li><li><a
href="http://akosma.com/2010/07/09/digital2-0/" rel="bookmark" title="July 9, 2010">digital2.0 iPad Application</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/" rel="bookmark" title="October 4, 2010">Integrating iOS Applications with Backend REST Services</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Smart Pointers in Objective-C++</title><link>http://akosma.com/2011/03/28/smart-pointers-in-objective-c/</link> <comments>http://akosma.com/2011/03/28/smart-pointers-in-objective-c/#comments</comments> <pubDate>Mon, 28 Mar 2011 14:31:15 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Open Source]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[C++]]></category> <category><![CDATA[Github]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[open source]]></category> <category><![CDATA[templates]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2920</guid> <description><![CDATA[One of the coolest features of C++ are templates, of which I&#8217;ve been drooling in the past. One of the most useful things that templates have brought to C++ are smart pointers, which simplify memory management tremendously; they combine the capacity of C++ to instantiate objects in the stack, the flexibility of heap allocation, and [...]]]></description> <content:encoded><![CDATA[<p>One of the coolest features of C++ are templates, of which <a
target="_blank" href="http://kosmaczewski.net/2008/03/13/templates/">I&#8217;ve been drooling in the past</a>. One of the most useful things that templates have brought to C++ are smart pointers, which simplify memory management tremendously; they combine the capacity of C++ to instantiate objects in the stack, the flexibility of heap allocation, and template classes, all in one thing.</p><p>I&#8217;ve talked about them in a <a
target="_blank" href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/">previous article in this blog</a>. In C++, a smart pointer will automatically call &#8220;delete&#8221; on the managed pointer when it goes out of scope, simplifying resource management and providing many more advantages over common pointers, as Andrei Alexandrescu explained in chapter 7 of his book <a
target="_blank" href="http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315">&#8220;Modern C++ Design&#8221;</a>.</p><p>In Objective-C, the &#8220;new&#8221; and &#8220;delete&#8221; keywords are replaced by some combination of &#8220;alloc / init&#8221;, &#8220;copy&#8221;, &#8220;release&#8221;, and &#8220;autorelease&#8221;. But given that Objective-C does not allow for stack allocation of objects (apart from blocks, but <a
target="_blank" href="http://www.mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html">that&#8217;s another story</a>), I&#8217;ve tried to create such a beast in Objective-C++. <span
id="more-2920"></span> These are the features of my smart pointer:</p><ul><li>It takes ownership of any non-autoreleased object with a retain count of at least 1.</li><li>It has value semantics, that is, it is copied by value from stack frame to stack frame, while the &#8220;owned&#8221; object, as any Objective-C entity, lives happily in the heap.</li><li>When it goes out of scope, its destructor is called, which sends a &#8220;release&#8221; message to the owned object.</li></ul><p>Here&#8217;s how you could use it:</p><div><pre class="brush:c">
for (NSInteger index = 0; index < 10; ++index)
{
    // A SmartPointer around an NSObject
    SmartPointer<NSObject> obj = SmartPointer<nsobject>::create();
    // SomeType is a typedef (see above)
    SomeType someObj = SomeType::create();
    // You can get access to the underlying Objective-C object
    // using "*", ".get()" or "()"; they all return the same pointer.
    // And once you have it, it's a normal Objective-C pointer
    // you can send messages to:
    SmartPointer<nsmutablearray> array = [*someObj createArrayWithCapacity:5];
    // Here a SmartPointer around an NSNumber
    NSNumber *value = [[NSNumber alloc] initWithInt:1424];
    SmartPointer<nsnumber> number = SmartPointer</nsnumber><nsnumber>(value);
    // Playing with the array we got above, just to show it's a normal object
    [array.get() addObject:@"test1"];
    [*array      addObject:@"test2"];
    [*array      addObject:number()];
    [array()     addObject:*obj];
    // After this NSLog call, in the console you should see
    // "[SomeClass dealloc]" which is printed when the SmartPointer goes
    // out of scope, sending the release message on the underlying pointer.
    NSLog(@"array %@", *array);
}
</nsnumber></nsmutablearray></nsobject></pre></div><p>In general, NSAutoreleasePools fit the bill quite comfortably in Objective-C for this kind of tasks, apart from some performance issues in iOS devices (particularly older iPhones and iPod touch devices), but I think there might be cases where just using a &#8220;non-autoreleased&#8221; approach to resource management might be useful, and typing an extra &#8220;[obj release]&#8221; line would be too much to ask <img
src='http://akosma.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Of course, this is just an experiment, that I just publish as part of my own curiosity. I would be more than glad to hear some feedback about it from people more knowledgeable in Objective-C and C++ than I am. The code, as usual, is <a
target="_blank" href="https://github.com/akosma/SmartPointerTest">available in Github</a> under a liberal BSD license. Enjoy!</p><p><strong>Update, 2011-03-28:</strong> just found by pure chance <a
href="http://www.levelofindirection.com/journal/2010/8/13/ocptr-a-smart-pointer-for-objective-c.html">another, much more complete</a>, implementation of this idea (note to self: always Google first!) with its <a
href="https://github.com/philsquared/OCPtr">code in Github</a>. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/" rel="bookmark" title="October 11, 2010">How knowing C and C++ can help you write better iPhone apps, part 1</a></li><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/" rel="bookmark" title="January 31, 2012">Determining Delegate Object Method Call Order in Objective-C with NSProxy</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2010/07/17/nib2objc-updated/" rel="bookmark" title="July 17, 2010">nib2objc updated</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2011/03/28/smart-pointers-in-objective-c/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>How knowing C and C++ can help you write better iPhone apps, part 1</title><link>http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/</link> <comments>http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/#comments</comments> <pubDate>Mon, 11 Oct 2010 06:15:35 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[C++]]></category> <category><![CDATA[code]]></category> <category><![CDATA[CPU]]></category> <category><![CDATA[heap]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[memory]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[stack]]></category> <category><![CDATA[technology]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2722</guid> <description><![CDATA[While learning how to write iOS applications, you will often encounter the phrase &#8220;learn C first&#8221;. Writers of Cocoa applications apparently benefit from knowing about C (sometimes even C++), but it is not very clear to many new developers how this actually works. The obvious question being &#8220;why should I learn C if actually I [...]]]></description> <content:encoded><![CDATA[<p>While learning how to write iOS applications, you will often encounter the phrase <a
target="_blank" href="http://stackoverflow.com/questions/180549/learn-c-first-before-learning-objective-c/180832#180832">&#8220;learn C first&#8221;</a>. Writers of Cocoa applications apparently benefit from knowing about C (sometimes even C++), but it is not very clear to many new developers how this actually works.</p><p>The obvious question being &#8220;why should I learn C if actually I have to use Objective-C to create my apps?&#8221;, and the answer &#8220;because Objective-C is a superset of C&#8221; is not really useful, albeit technically correct.</p><p>This series of two articles will provide some pointers (no pun intended) to answer that question, in the hopes that new iOS developers will get a copy of the <a
target="_blank" href="http://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628%3FSubscriptionId%3D0F0YTN83N46JSX6KDT02%26tag%3Dakosmasoftwar-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0131103628">K&amp;R</a> and the <a
target="_blank" href="http://www.amazon.com/C-Programming-Language-Special/dp/0201700735%3FSubscriptionId%3D0F0YTN83N46JSX6KDT02%26tag%3Dakosmasoftwar-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201700735">Stroustrup</a> books soon.</p><h2>Objective-C</h2><p>Before starting with this article, I would like to remind my readers about some key facts of Objective-C, often overlooked by tutorials and teachers, and which explains much of the characteristics of Cocoa as well:</p><ol><li>All methods (at instance and / or class level) are public, virtual and overridable. You can have @public, @private and @protected instance variables (also known as &#8220;ivars&#8221;), but methods are public. And yes, you can override class methods in subclasses, too, which is not a very common pattern (you can do that in C++ through templates, though). <a
target="_blank" href="http://en.wikipedia.org/wiki/Type_polymorphism">Polymorphism is the key to understanding Objective-C.</a></li><li>There is no formal concept of abstract classes. You can override the alloc and init methods of some class to avoid creating instances from it, but a priori, you can create an instance from almost any class.</li><li>You can have as many &#8220;root classes&#8221; as you want. You are not forced to inherit from NSObject, although in most cases that is what you do. In Cocoa there are two root classes already defined for developers to use: NSObject and NSProxy.</li><li>There is no concept of namespaces. That explains the prefix crazyness all over the place, because all classes live in the same planet, so you should better use a nice prefix for your stuff. In my case I usually publish my classes with the &#8220;AKO&#8221; prefix.</li></ol><p><span
id="more-2722"></span></p><h2>Stack and Heap</h2><p>This is the probably the most important thing to know about iOS programming. Many developers, particularly those coming from Java, .NET, PHP or other garbage-collected environments, just don&#8217;t know that the computer memory used by applications is not a uniform space, and that running code uses space in three different, yet complementary, regions of memory, or as computer scientists refer to them, &#8220;segments&#8221;: <a
target="_blank" href="http://www.ualberta.ca/CNS/RESEARCH/LinuxClusters/mem.html">the text, the stack and the heap.</a> <a
target="_blank" href="http://www.boundscheck.com/knowledge-base/c-cpp/memory-layout-in-c/342/"><img
src="http://akosma.com/wp/wp-content/uploads/2010/10/MemoryLayout.gif" alt="MemoryLayout.gif" border="0" width="440" height="344" class="alignnone size-medium" /></a></p><p>The &#8220;text segment&#8221; is where the application code lives in memory while your application runs. Every instruction is there, every single function and procedure and method and executable code lives in that part of memory until your application exits. Usually you don&#8217;t really have to know anything about the text segment, other that it is there.</p><p>When the application starts, the main() function is called and some space is allocated in the &#8220;stack&#8221;. This is another segment of memory allocated for your application, and that&#8217;s where the memory required for the variables of your functions are allocated. Each time you call a function in your program, a section of the stack called a &#8220;frame&#8221; is allocated in the stack. The local variables of this new function are allocated there.</p><p><a
target="_blank" href="http://www.futuregov.asia/photologue/photo/2008/aug/30/stack-papers/"><img
src="http://akosma.com/wp/wp-content/uploads/2010/10/paper_stack_gallery_display.jpg" alt="paper_stack_gallery_display.jpg" border="0" width="170" height="170" class="alignleft size-full" /></a></p><p>As the name implies, the stack is a &#8220;last in &amp; first out&#8221; (or LIFO) structure, and when functions call other functions, stack frames are created; when those functions exit, their frames are destroyed automatically (that&#8217;s why stack objects are usually referred to as &#8220;automatic&#8221; objects). In your code, an &#8220;end&#8221; statement or a closing curly brackets &#8220;}&#8221; visually indicate a delimiter of stack context; when the current execution goes beyond that element, you can be sure that the stack frame is gone.</p><p>The stack region is at the origin of the &#8220;stack overflow&#8221; concept, which frequently happens when using recursive functions; you allocate too many frames, and you run out of space in the stack. Boom. Another interesting problem associated with stacks is that of &#8220;buffer overflows&#8221;, which constitutes one of the most common security problems caused by badly written C code. When you write memory contents in the stack, and you don&#8217;t check the size of your structures, you might end up writing something on the text segment&#8230; which basically means that you might as well be rewriting the code of the application, as it runs. Bad, very bad things can happen then.</p><p><a
target="_blank" href="http://linguiniontheceiling.blogspot.com/2008/10/thats-madame-trash-heap-to-you.html"><img
src="http://akosma.com/wp/wp-content/uploads/2010/10/trash-heap2.jpg" alt="trash heap.jpg" border="0" width="170" height="172" class="alignleft size-full" /></a></p><p>Finally, the &#8220;heap&#8221; (also called the &#8220;data&#8221; segment) provides a storage medium that can last throughout the execution of functions; global and static variables live on the heap, until the application exits. To access whatever data you have created in the heap, you require at least one &#8220;pointer&#8221; on the stack, because that&#8217;s how your CPU can access data in the heap; through the stack. You can think of a pointer as just an integer variable that holds the number of a particular memory address in the heap (it is actually a bit more complicated, but that&#8217;s the basic picture).</p><p>To summarize: the CPU uses the value of the pointer in the stack to access or, as they say, &#8220;dereference&#8221;, the structure in the heap. Without pointer on the stack, no access to the object on the heap. And here lies the reason of all memory leaks: if you lose your pointer for whatever reason, then you have lost track of an object in the heap. And given that the heap is cleared only when your application exits, you have &#8220;leaked&#8221; memory, and you will never be able to recover it again (unless you restart your program, that is, but we don&#8217;t want to ask your user to quit and restart to solve that problem, do we?).</p><p>In C++ you can create objects in both the stack and the heap, and to know how to differentiate between both regions, you have to pay attention to the syntax used to create them:</p><div><pre class="brush:c">
// The variable does not use a "star"!
// Created on the stack, don't use "new"
SomeClass stackObject;
// do not call delete stackObject!!!
// Pay attention to the "star"...
// it's a pointer on the stack!
// We are initializing it to NULL,
// as a rule of thumb.
SomeClass *heapObject = NULL;
// And to create the object, use "new"
// to have it created on the heap
heapObject = new SomeClass;
// you must call this to avoid a leak!
delete heapObject;
</pre></div><p>In the case of the stack object, its destructor is called automatically when the stack frame is removed. In the case of the heap object, what goes away is the pointer variable in the stack&#8230; but not the object on the heap! To avoid that problem, in C you have to balance every malloc() (or calloc() or similar function) with a free(). In C++ you have to balance every call to &#8220;new&#8221; with a call to &#8220;delete&#8221;.</p><p>Now, imagine for a second that you have an object in the stack (an automatic object) that points to some other object in the heap, and that our first object is prepared to call the destructor of the second one. This is how the <a
target="_blank" href="http://en.wikipedia.org/wiki/Auto_ptr">auto_ptr</a> (or &#8220;smart pointer&#8221;) class of the standard C++ template library (STL) works; it takes advantage of the fact that variables on the stack are automatic. Instead of having to manage manually the lifecycle of your objects, an auto_ptr object on the stack will call delete automatically when it goes out of scope:</p><div><pre class="brush:c">
#include <iostream>
#include <memory>
using namespace std;
int main(int argc, char **argv)
{
    // created on the heap
    SomeClass *heapObject = new SomeClass;
    // now the stackPointer owns the heapObject
    auto_ptr<someclass> auto(heapObject);
    // Print non-NULL address of heapObject
    cout < < auto.get() << endl;
    // no need to call delete here!
    // "auto" is an stack object that
    // "owns" heapObject
    // (see below for a discussion
    // about ownership!)
    // and will call the destructor of heapObject
    // automatically when required. Magic!
}
</pre></someclass></memory></iostream></pre></div><p>How does all of this apply to Objective-C? Well, it turns out that the current versions of Objective-C only allow us to create objects on the heap. Apparently creating objects on the stack was possible in early versions of Objective-C, but that isn't the case anymore. All objects that you manipulate in Objective-C live in the heap (*), and as such, if you lose the pointer to them, you have a memory leak. Here goes some code in Objective-C with an obvious memory leak:</p><div><pre class="brush:objc">
- (void)doSomething
{
    NSObject *obj = [[NSObject alloc] init];
    // do something else with obj...
    // and now we forget to release, and boom:
    // Memory leak! This is because the
    // "obj" pointer in the stack is lost
    // when this stack frame is removed...
    // ... but the heap object stays!
}
</pre></div><p>What can you do to avoid that? Two things:</p><ol><li>Remember how in C you balance malloc() with free, and how you balance "new" with "delete" in C++? Well, in Objective-C you have to balance every call to "alloc", "copy" or "retain" with a "release".</li><li>You can also use the "autorelease" method, to add your object to the current autorelease pool, so that it will be automatically disposed of in the next iteration of the run loop cycle. OK, this is slightly more complex, but basically this also solves the memory leak problem.</li></ol><p>Here goes some code illustrating the two solutions in detail:</p><div><pre class="brush:objc">
// First solution
- (void)doSomething
{
    NSObject *obj = [[NSObject alloc] init];
    // do something else with obj...
    [obj release];
}
// Second solution
- (void)doSomething
{
    NSObject *obj = nil;
    obj = [[[NSObject alloc] init] autorelease];
    // do something else with obj...
    // Don't release obj! The object referenced
    // by that pointer will be disposed
    // in the next run loop iteration.
}
</pre></div><p>However, please, please, avoid the following code, which stretches the use of the autorelease pool to the level of abuse(**):</p><div><pre class="brush:objc">
for (NSData *data in veryLargeArrayWithImages)
{
    UIImage *image = [UIImage imagedWithData:data];
    // do something with image
}
</pre></div><p>because this will create an unnecessary large number of instances that will remain in memory until the next run loop cycle (which will probably happen after the end of the current loop, that is, in a long CPU time in the future). Instead, either use a temporary autorelease pool, or use the non-autoreleased version of the code above (which I prefer, particularly in the iPhone):</p><div><pre class="brush:objc">
for (NSData *data in veryLargeArrayWithImages)
{
    UIImage *image = [[UIImage alloc] initWithData:data];
    // do something with image
    [image release];
}
</pre></div><p>All of these memory management techniques are explained in detail in my article <a
target="_blank" href="http://akosma.com/2009/01/28/10-iphone-memory-management-tips/">10 iPhone Memory Management Tips</a>.</p><p>Mike Ash has written an extensive <a
target="_blank" href="http://www.mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html">article about stack and heap objects</a> that will help you understand all of these issues even better. Finally, to see visually how the stack and the heap collaborate with each other, and how to keep an object-oriented mindset when writing code in C, I recommend watching on iTunesU the excellent <a
target="_blank" href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=384233005">Programming Paradigm</a> course by professor Jerry Cain from Stanford University.</p><h2>Object ownership</h2><p>Ownership is a key concept in C++ memory management: whenever an object creates or copies another, the first one becomes the "owner" of the second. And as such, it is the task of the first one to destroy the second. Here goes some code that shows that pattern; here some class requires another one, and the ownership relationship is enforced throughout the lifetime of both objects.</p><div><pre class="brush:c">
// Forward declaration of some owned class
class Owned;
// Declaration of the owner
class OwnerClass : BaseClass
{
public:
    OwnerClass();
    virtual ~OwnerClass();
    const Owned&amp; getOwnedObject();
private:
    Owned* _owned;
};
// Constructor implementation
OwnerClass::OwnerClass()
: BaseClass()
, _owned(new Owned)
{
}
// Destructor implementation
OwnerClass::~OwnerClass()
{
    delete _owned;
}
// Provide to clients a reference
// to the underlying owned object
const Owned&amp; OwnerClass::getOwnedObject()
{
    return _owned;
}
</pre></div><p>In Objective-C, the chain of ownership is important to solve the problem of circular references; this is a common problem when creating delegation relationships between objects. When an object is delegate of another, the reference between the object and its delegate must be weak:</p><div><pre class="brush:objc">
// A delegate protocol declaration
@protocol OwnedDelegate <nsobject>
@optional
- (void)ownedObjectSaysSomething:(Owned *)owned;
@end
// Interface of the owner
@interface OwnerClass : NSObject <owneddelegate>
{
@private
    Owned *_owned;
}
@property (nonatomic, retain) Owned *owned;
@end
// Interface of the owned
@interface Owned : NSObject
{
@private
    id</owneddelegate><owneddelegate> _delegate;
}
@property (nonatomic, assign) id</owneddelegate><owneddelegate> delegate;
@end
</owneddelegate></nsobject></pre></div><p>Pay attention at the @property declarations in the code above. The OwnerClass "retains" the Owned object, but the Owned class just "assigns" the delegate. This way, we know clearly who's responsible of releasing who: it is the OwnerClass dealloc method that will do that, and not the other way around!</p><div><pre class="brush:objc">
@implementation OwnerClass
@synthesize owned = _owned;
- (id)init
{
    if (self = [super init])
    {
        _owned = [[Owned alloc] init];
        _owned.delegate = self;
    }
    return self;
}
- (void)dealloc
{
    _owned.delegate = nil;
    [_owned release];
    _owned = nil;
    [super dealloc];
}
#pragma mark -
#pragma mark OwnedDelegate protocol
- (void)ownedObjectSaysSomething:(Owned *)owned
{
    // do something now
}
@end
</pre></div><p>If you don't follow this pattern, you might end up with a circular reference, and the reference counting scheme of Objective-C won't be able to solve this problem, which means that you might end up leaking two instances at once!</p><h2>free() vs. delete vs. dealloc</h2><p>In C, free() is a function taking any pointer as parameter, and whose purpose is to mark the region of memory pointed by the parameter as available for the application. It is up to the application developer to pay attention to properly clean any owned objects in the structures stored in that region, as the standard C runtime makes no assumptions whatsoever about those secondary relations.</p><p>In C++, delete is an operator, and its task is to ultimately call the destructor of the target object, starting by the class of the current object, until it reaches the last class in the inheritance chain, and it does this immediately when called, in a synchronous fashion. Your constructors do not have to call the constructor of the base class in their implementation; it is, however, strongly recommended to <a
target="_blank" href="http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7">mark your destructors as virtual</a>, to ensure that the delete operator does this in all cases.</p><p>On the other hand, dealloc in Objective-C is a polymorphic, virtual, overridable method, not an operator neither a function, and it is never called directly by your code. It is called in a kind of asynchronous fashion, when the current run loop ends, and when the retain count of the current object reaches zero. This means that you might not know exactly when that happens, and actually, you shouldn't care. The important thing is to release all the things you were holding on to (see the "object ownership" section above).</p><p>Another important fact of dealloc is that, being polymorphic, only the implementation of the current class will be called, so you must always remember to add a call to [super dealloc] at the end of your own dealloc. And always, always add it at the end, <a
target="_blank" href="http://stackoverflow.com/questions/909856/why-do-i-have-to-call-super-dealloc-last-and-not-first/909925#909925">not at the beginning</a>, of your own dealloc.</p><h2>Conclusion</h2><p>I hope this information will be useful to developers new to the iOS platform. Objective-C and Cocoa share many characteristics with other similar platforms and frameworks written in C and C++, and developers working with garbage-collected runtimes are not used to know the layout of structures in memory. I think, however, that knowing this is useful also in such environments.</p><p>In the second part of this series I will dive into variable initialization, bitwise masks, functions and other related aspects of C and C++ programming, and how they relate to Objective-C.</p><p>Acknowledgement: Many thanks to <a
target="_blank" href="http://volonbolon.net/">Ariel Rodríguez</a> for reviewing early drafts of this post.</p><p>(*) Well, that is not entirely true; there is one kind of Objective-C object that lives in the stack, and that is <a
target="_blank" href="http://www.mikeash.com/pyblog/friday-qa-2008-12-26.html">blocks</a>. But this is an exception, one that I will tackle in a separate blog post.</p><p>(**) Autorelease pools are definitely material for another blog post.</p><p><strong>Update, 2010-10-13:</strong> Ariel has written an excellent follow up to this article, <a
target="_blank" href="http://volonbolon.net/post/1305559150/stack-overflow">explaining the problem of stack overflows</a>. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/03/28/smart-pointers-in-objective-c/" rel="bookmark" title="March 28, 2011">Smart Pointers in Objective-C++</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/" rel="bookmark" title="January 31, 2012">Determining Delegate Object Method Call Order in Objective-C with NSProxy</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Integrating iOS Applications with Backend REST Services</title><link>http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/</link> <comments>http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/#comments</comments> <pubDate>Mon, 04 Oct 2010 15:22:14 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[iPad]]></category> <category><![CDATA[REST]]></category> <category><![CDATA[Web services]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2707</guid> <description><![CDATA[A couple of hours ago I finished my presentation at JAOO, a discussion of what I&#8217;ve learnt about integrating REST services in iOS apps while creating the iPhoneWebServicesClient project at Github. This project showcases different transport formats and libraries to consume web services from an iPhone application. It features a server application written in PHP, [...]]]></description> <content:encoded><![CDATA[<p>A couple of hours ago I finished <a
target="_blank" href="http://jaoo.dk/aarhus-2010/presentation/Accessing%20Web%20Services%20From%20iPhone%20and%20iPad%20Applications">my presentation at JAOO</a>, a discussion of what I&#8217;ve learnt about integrating REST services in iOS apps while creating the <a
target="_blank" href="http://github.com/akosma/iPhoneWebServicesClient">iPhoneWebServicesClient project at Github</a>.</p><p>This project showcases different transport formats and libraries to consume web services from an iPhone application. It features a server application written in PHP, a command-line script that saves the output of the server application in different formats, and an iPhone client application (compatible with iPhone OS 3.0 and higher). The server application reads a MySQL database and outputs data in the following formats: HTML, JSON, YAML, XML (arbitrary format), SOAP, Property list (Binary and XML), CSV, and Protocol Buffers.</p><p>As promised, here go the slides and of course, check the <a
target="_blank" href="http://github.com/akosma/iPhoneWebServicesClient">project in Github</a> which actually contains the real thing!</p><div
style="width:425px" id="__ss_5353512"><strong
style="display:block;margin:12px 0 4px"><a
href="http://www.slideshare.net/akosma/integrating-ios-applications-with-backend-rest-services" title="Integrating iOS Applications with Backend REST Services">Integrating iOS Applications with Backend REST Services</a></strong><object
id="__sse5353512" width="425" height="355"><param
name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=restiphoneclient-101004100516-phpapp02&#038;stripped_title=integrating-ios-applications-with-backend-rest-services&#038;userName=akosma" /><param
name="allowFullScreen" value="true"/><param
name="allowScriptAccess" value="always"/><embed
name="__sse5353512" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=restiphoneclient-101004100516-phpapp02&#038;stripped_title=integrating-ios-applications-with-backend-rest-services&#038;userName=akosma" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div
style="padding:5px 0 12px">View more <a
href="http://www.slideshare.net/">presentations</a> from <a
href="http://www.slideshare.net/akosma">Adrian Kosmaczewski</a>.</div></div><p>Although <a
target="_blank" href="http://www.version2.dk/artikel/16464-jaoo-den-foerste-roede-seddel">not everyone liked it</a> (you definitely can&#8217;t please everyone) I&#8217;ve got good feedback from many other attendees and all in all I&#8217;m happy to have shared what I&#8217;ve learnt in this project. Feel free to fork the code and add support for other libraries and configurations! I&#8217;d love to receive feedback about this project. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/04/30/presentations-at-sdc-2011/" rel="bookmark" title="April 30, 2011">Presentations at SDC 2011</a></li><li><a
href="http://akosma.com/2011/03/31/talking-at-the-scandinavian-developer-conference-2011/" rel="bookmark" title="March 31, 2011">Talking at the Scandinavian Developer Conference 2011</a></li><li><a
href="http://akosma.com/2011/12/29/trainings-2012-advanced-ios-mobile-web-apps-and-node-js/" rel="bookmark" title="December 29, 2011">Trainings 2012: Advanced iOS, Mobile Web Apps and Node.js</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2012/01/30/how-we-work/" rel="bookmark" title="January 30, 2012">How we work</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Migrating iPhone 3.x apps to iPad and iOS 4.0</title><link>http://akosma.com/2010/07/26/migrating-iphone-3-x-apps-to-ipad-and-ios-4-0/</link> <comments>http://akosma.com/2010/07/26/migrating-iphone-3-x-apps-to-ipad-and-ios-4-0/#comments</comments> <pubDate>Mon, 26 Jul 2010 08:43:30 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[migration]]></category> <category><![CDATA[technology]]></category> <category><![CDATA[Xcode]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2597</guid> <description><![CDATA[Right now, creating Universal Applications for the iPod touch, the iPhone and the iPad is not really a straightforward task. The current panorama of iOS-compatible software and hardware platforms is getting more and more complex, and this blog post is a small guide (by no means exhaustive) of tips and tricks that have helped me [...]]]></description> <content:encoded><![CDATA[<p>Right now, creating <a
target="_blank" href="http://devimages.apple.com/iphone/resources/introductiontouniversalapps.pdf">Universal Applications</a> for the iPod touch, the iPhone and the iPad is not really a straightforward task. The current panorama of iOS-compatible software and hardware platforms is getting more and more complex, and this blog post is a small guide (by no means exhaustive) of tips and tricks that have helped me get my apps running in as many platforms as possible, with as few headaches as possible.</p><p>First of all, a few warnings:</p><ul><li>I assume your current applications run in iPhone OS 3.1 as a minimum requirement. Apple does not accept any more applications targeting the 2.x frameworks these days, and the developer tools do not include those anymore.</li><li>I assume your projects <a
target="_blank" href="http://akosma.com/2009/07/16/objective-c-compiler-warnings/">compile and link without warnings</a>; many API calls have been deprecated between 2.x and 4.0, so you&#8217;d better have code using the latest methods and no deprecated ones.</li></ul><h2>Panorama</h2><p>Waiting for an unification of the iPad and the iOS 4 frameworks (probably <a
target="_blank" href="http://adage.com/digital/article?article_id=144670">later this year</a>), the current panorama of software and hardware iOS platforms looks as follows:</p><table
border="1" width="100%"><tr><th
style="text-align: center" rowspan="2" width="25%"></th><th
style="text-align: center" colspan="3" width="25%">iPhone</th><th
style="text-align: center" colspan="2" width="25%">iPod touch</th><th
style="text-align: center" rowspan="2" width="25%">iPad</th></tr><tr><th
style="text-align: center" width="8.3%">3G</th><th
style="text-align: center" width="8.3%">3GS</th><th
style="text-align: center" width="8.3%">4</th><th
style="text-align: center" width="12.5%">2nd gen</th><th
style="text-align: center" width="12.5%">3rd gen</th></tr><tr><td
style="text-align: center"><strong>iPhone OS 3.1</strong></td><td
style="text-align: center"> <strong>x</strong></td><td
style="text-align: center"> <strong>x</strong></td><td></td><td
style="text-align: center"> <strong>x</strong></td><td
style="text-align: center"> <strong>x</strong></td><td></td></tr><tr><td
style="text-align: center"><strong>iPhone OS 3.2</strong></td><td></td><td></td><td></td><td></td><td></td><td
style="text-align: center"> <strong>x</strong></td></tr><tr><td
style="text-align: center"><strong>iOS 4.0</strong></td><td></td><td
style="text-align: center"> (ls)</td><td
style="text-align: center"> <strong>x</strong></td><td
style="text-align: center"> (ls)</td><td
style="text-align: center"> <strong>x</strong></td><td></td></tr><tr><td
style="text-align: center"><strong>Year Released</strong></td><td
style="text-align: center"> 2008</td><td
style="text-align: center"> 2009</td><td
style="text-align: center"> 2010</td><td
style="text-align: center"> 2008</td><td
style="text-align: center"> 2009</td><td
style="text-align: center"> 2010</td></tr><tr><td
style="text-align: center"><strong>RAM (MB)</strong></td><td
style="text-align: center"> 128</td><td
style="text-align: center"> 256</td><td
style="text-align: center"> 512</td><td
style="text-align: center"> 128</td><td
style="text-align: center"> 256</td><td
style="text-align: center"> 256</td></tr><tr><td
style="text-align: center"><strong>CPU (MHz)</strong></td><td
style="text-align: center"> 620</td><td
style="text-align: center"> 833</td><td
style="text-align: center"> 1 GHz</td><td
style="text-align: center"> 620</td><td
style="text-align: center"> 833</td><td
style="text-align: center"> 1 GHz</td></tr></table><p>(ls): limited support, particularly for multitasking.</p><p>For practical purposes, I&#8217;ve omitted in the table above the fact that the iPhone 3G is (theoretically) able to run iOS 4. Something that has been empirically proved to be a <a
target="_blank" href="http://www.tuaw.com/2010/07/22/ios-4-and-iphone-3g-is-a-match-made-in-whats-the-opposite-of/">bad idea</a>. <span
id="more-2597"></span> <img
src="http://akosma.com/wp/wp-content/uploads/2010/07/ios4_icon_20100624.png" alt="ios4_icon_20100624.png" border="0" width="170" height="73" class="alignleft size-full" /></p><h2>Upgrading Xcode Projects to iOS 4</h2><p>Your Xcode 3.1 iPhone project can be migrated to iOS 4 as follows:</p><ul><li>If you are using an SCM with branching support, create a new branch for all of the operations below; you don&#8217;t want to impact your &#8220;trunk&#8221;, or main branch with all these changes, as more urgent bugs might appear while you are doing this.</li><li>Download the <a
target="_blank" href="http://developer.apple.com/iphone/">latest SDK from Apple</a>. This is required by Apple, actually. And the latest version of Xcode (3.2.3 at the time of this writing) allows you to write applications compatible with all the platforms in the table above.</li><li>Open your project with Xcode 3.2.3; select the &#8220;Project / Edit Project Settings&#8230;&#8221; menu and change the &#8220;Base SDK value to iPhone Device 4.0 (yes, even if your project is meant to target iPhone OS 3.1&#8230; stay with me!)</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/default_sdk_xcode1.png" alt="default_sdk_xcode.png" border="0" width="440" height="608" class="alignnone size-medium" /></p><ul><li>In the &#8220;Targets&#8221; group of your Xcode project, open the &#8220;Info&#8221; panel, select the &#8220;Build&#8221; tab and change the &#8220;iPhone OS Deployment Target&#8221; entry for all the configurations of your target to &#8220;iPhone OS 3.1&#8243;. This will allow your code to be loaded in earlier versions of iOS, even if your application uses iOS 4 as a base SDK for all configurations:</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/deployment_target_xcode.png" alt="deployment_target_xcode.png" border="0" width="440" height="608" class="alignnone size-medium" /></p><ul><li>Set the UIKit framework, as well as any new framework provided by iOS 4, to link as &#8220;Weak&#8221;; for example, in the screenshot below, taken from the settings of <a
target="_blank" href="http://github.com/akosma/Senbei">my open source Senbei application</a>, you can see that UIKit is weakly linked, as well as the MobileCoreServices framework (which does not exist in iPhone OS 3). This prevents the application from crashing at startup in versions of iOS earlier than 4, because newer versions of UIKit bring new classes and APIs that were not available before:</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/weak_type_framework.png" alt="weak_type_framework.png" border="0" width="440" height="630" class="alignnone size-medium" /></p><ul><li>Change your Entitlements.plist file, because iOS 4 applications submitted to the App Store require a new format in the Entitlements.plist file. In most cases, you can just delete the previous file, and create a new one from Xcode (&#8220;File / New File&#8230;&#8221;, then select &#8220;Code Signing / Entitlements&#8221; in the dialog that appears).</li></ul><p>Old Entitlements.plist:</p><div><pre class="brush:xml">
< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>get-task-allow</key>
    <false />
</dict>
</plist>
</pre></div><p>New Entitlements.plist:</p><div><pre class="brush:xml">
< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    
    <key>application-identifier</key>
    <string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
    <key>keychain-access-groups</key>
    <array>
        <string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
    </array>
    
</dict>
</plist>
</pre></div><ul><li>Update your icons and graphics for the new &#8220;Retina&#8221; display of the iPhone 4; <a
target="_blank" href="http://developer.apple.com/iphone/library/qa/qa2010/qa1686.html">Apple has published a special guide</a> that provides all the information required in terms of sizes, formats and naming conventions.</li></ul><p>After doing the steps above, you should have an application running on iPhone OS 3.1, 3.2 (as an iPhone application) and 4.0, offering exactly the same functionality and ready to be sent to the App Store.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/03/ipadbooks.png" alt="ipadbooks.png" border="0" width="170" height="206" class="alignleft size-full" /></p><h2>Create a Universal iPhone and iPad application</h2><p>Creating an iPad-compatible application from your iPhone app requires much more than just adapting your source code; the user experience of iPad apps is a completely different beast than that of iPhone apps, so I strongly recommend you <a
target="_blank" href="http://www.smashingmagazine.com/2010/04/16/design-tips-for-your-ipad-app/">ask a graphic and/or UX designer for help</a>. I can&#8217;t stress this too much; iPad apps aren&#8217;t just &#8220;big&#8221; iPhone apps. They are much, much more.</p><p>Technically speaking, in the simplest of terms, you should be able to migrate most UIKit-based application following the standard path provided by Apple:</p><ul><li>Select your target in Xcode and choose the &#8220;Project / Upgrade Current Target for iPad&#8230;&#8221; menu.</li><li>Use some compile-time and runtime tricks to get different parts of your code to execute in different environments, as explained by <a
target="_blank" href="http://iphonedevelopment.blogspot.com/2010/04/few-more-notes-on-creating-universal.html">Jeff LaMarche</a>:</li></ul><div><pre class="brush:objc">
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        NSLog(@"iPad Idiom");
    else
#else
        NSLog(@"iPhone Idiom");
#endif
</pre></div><h2>Testing your code in different devices</h2><p>My advice is the following: don&#8217;t upgrade your old iPhone to iOS 4, particularly if you own a 3G. Keep it running under 3.1 and get the new iPhone 4 as soon as you can. This has two major advantages:</p><ul><li>You will be sure that there aren&#8217;t crashes or unexpected situations in iPhone OS 3.1, particularly when you are using new APIs in your code.</li><li>The iPhone 3G and 3GS are slower than the new iPhone 4, but they are still (probably not for long) the most widely deployed, particularly in those countries where the iPhone 4 has not yet been released. This will help you create code that uses low memory, and that runs faster in newer models.</li></ul><p>In my personal situation, I have my old iPhone 3G running iPhone OS 3.1.3, and a second generation iPod touch running iOS 4. And of course, my iPad runs iPhone OS 3.2.1.</p><h2>Adapting your code for different platforms</h2><p>Although <a
target="_blank" href="http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html">Apple recommends using the UI_USER_INTERFACE_IDIOM macro</a>, sometimes you need a tighter control in your code. For this, I have used three different techniques:</p><ul><li>Use a different class as the app delegate in your iPad application; instead of making your code a mess of &#8220;if&#8221; and &#8220;else&#8221; statements or preprocessor routines, make your iPad application create an instance of a different class, one that might or might not be a child class of the existing application delegate. This way, you can completely separate the code of both platforms, and each can load a different UI control hierarchy, without impacting the existing iPhone OS 3.1 or iOS 4.0 infrastructure.<br
/> You can specify a different class for your iPad app delegate directly in your MainWindow-iPad.xib file, created for you when you selected the &#8220;Project / Upgrade Current Target for iPad&#8230;&#8221; menu (one more advantage of using Interface Builder files in your projects!):</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/mainwindow_xib_ipad.png" alt="mainwindow_xib_ipad.png" border="0" width="440" height="255" class="alignnone size-medium" /></p><ul><li>Check for symbols at runtime, taking advantage of the dynamic nature of Objective-C; for example, the code below only executes in iOS 4 or later, because the ADBannerView is not available in previous versions of the iPhone OS. This code will run without problems in iPhone OS 3.1! You can also use NSObject&#8217;s &#8220;respondToSelector:&#8221; method to perform runtime checks of the capabilities of your current platform, which might help you branch your code in different directions depending on the context:</li></ul><div><pre class="brush:objc">
- (void)showAdvertising
{
    Class klass = NSClassFromString(@"ADBannerView");
    if (klass)
    {
        ADBannerView *adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0.0, 416.0, 320.0, 50.0)];
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
        adView.delegate = self;
        [self.view addSubview:adView];
    }
}
</pre></div><ul><li>Include and use in your project the <a
target="_blank" href="http://github.com/erica/uidevice-extension">UIDevice extensions by Erica Sadun</a>. This very handy set of categories provides a wealth of options, making your code much more readable and easier to understand. Most importantly, it is actively maintained by Erica, and this means that future versions of the categories will be able to detect more features of iOS.</li></ul><p>Finally, MPMoviePlayerController requires special attention, because it&#8217;s widely used in many applications and also because it has been greatly improved (and changed) between iPhone OS 3.1, iPhone OS 3.2 and iOS 4. Those changes include, in some cases, deprecated APIs, so here I&#8217;ll just link to <a
target="_blank" href="http://iphonedevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html">this excellent article by John Muchow</a> in the iPhone Developer Tips blog, which explains all the problems and the possible solutions.</p><h2>Conclusion</h2><p>As you could see, creating universal apps is not easy, but it isn&#8217;t impossible either; it requires a bit of attention and lots of testing. Do you have any tips or links that you would like to share? Feel free to add more information in the comments below. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/07/18/more-nib2objc-fun/" rel="bookmark" title="July 18, 2010">More nib2objc fun</a></li><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2011/08/23/dropping-support-for-iphone-os-3-x/" rel="bookmark" title="August 23, 2011">Dropping support for iPhone OS 3.x</a></li><li><a
href="http://akosma.com/2010/07/09/digital2-0/" rel="bookmark" title="July 9, 2010">digital2.0 iPad Application</a></li><li><a
href="http://akosma.com/2011/09/13/a-shift-in-the-market-towards-mobile-web-apps/" rel="bookmark" title="September 13, 2011">A Shift In The Market Towards Mobile Web Apps</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/07/26/migrating-iphone-3-x-apps-to-ipad-and-ios-4-0/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Core Text Objective-C Wrapper</title><link>http://akosma.com/2010/07/08/core-text-objective-c-wrapper/</link> <comments>http://akosma.com/2010/07/08/core-text-objective-c-wrapper/#comments</comments> <pubDate>Thu, 08 Jul 2010 10:38:53 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[Core Text]]></category> <category><![CDATA[fonts]]></category> <category><![CDATA[frameworks]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[style]]></category> <category><![CDATA[technology]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2541</guid> <description><![CDATA[One of the most promising and mysterious new frameworks introduced in iOS 3.2 is Core Text. Apple defines Core Text as a &#8220;text drawing engine&#8221;, which allows Mac (and now iPad) apps to render rich text on any graphics context. Strings drawn with Core Text feature lots of custom settings such as detailed font information, [...]]]></description> <content:encoded><![CDATA[<p>One of the most promising and mysterious new frameworks introduced in iOS 3.2 is Core Text. Apple defines Core Text as a &#8220;text drawing engine&#8221;, which allows Mac (and now iPad) apps to render rich text on any graphics context. Strings drawn with Core Text feature lots of custom settings such as detailed font information, columns, variable line and paragraph heights and several different attributes, which designers and font aficionados surely understand much better than I do. Many new apps have been using this framework since the release of the iPad, particularly newspapers and ebook reader applications, rendering gorgeous text in custom fonts, many of them not available natively in iOS. This framework is also used in lifestyle and corporate applications, too, where using a custom font is sometimes required to match the specifications of brands and trademarks. <img
src="http://akosma.com/wp/wp-content/uploads/2010/07/coretextwrapper.png" alt="coretextwrapper.png" border="0" width="440" height="300" class="alignnone size-medium" /><span
id="more-2541"></span>It is very important to understand that Core Text is really just a text drawing engine to be used on top of Quartz (Core Graphics), to render rich text on any graphics context. Core Text cannot be used to create a rich text editor, for example, so don&#8217;t expect to extend UITextView with it. But you can use it to draw any kind of rich text on screen, which can make you avoid using UIWebView instances for that.</p><p>One of the most interesting capabilities of Core Text is being able to render text in several columns. However, Core Test is a C-based framework, and I think that understanding and using the concepts and structures required to render text in columns can be particularly tricky. To make the my life and that of my fellow developers easier, I&#8217;ve created a small set of Objective-C classes that encapsulate the creation of framesetters, attributed strings and other constructions, and takes care of the creation of several columns, as well as the division of the text in several pages if required.</p><p>The API interface is very simple (in purpose) and I&#8217;m pretty sure you&#8217;ll be able to integrate it very easily in your own projects, particularly if you look at the sample project where the classes are used. I&#8217;ve also added a category for UIFont, that returns the associated CTFontRef pointer, in a similar fashion to UIImage, which is able to return a pointer to the underlying CGImageRef pointer. It also allows to create a CTFontRef from any font embedded in the application bundle. I am puzzled that the framework designers haven&#8217;t included this by default in UIKit.</p><p>A future extension I&#8217;d like to add would be a couple of categories to parse simple RTF or HTML strings (to start with, probably just with bold and italic text) and create the appropriate attributed string from it; there&#8217;s a couple of AppKit extensions to NSAttributedString that do exactly that, but for the moment they are only available in the Mac version of Cocoa, and I haven&#8217;t found anything similar for iOS yet (feel free to leave a comment below if you know about some implementation for generating NSAttributedStrings from HTML or RTF text!)</p><p>The code, as usual, is available through <a
target="_blank" href="http://github.com/akosma/CoreTextWrapper">Github</a> (BSD license), so feel free to use it and even contribute bug fixes or enhancements if you want. The font embedded in the project is Polsku Regula, <a
target="_blank" href="http://openfontlibrary.org/files/ospublish/140">available through the Open Font Library.org</a>. The project requires Xcode 3.2.3 and the iOS SDK 4.0, and it creates a simple application that works on the iPad (iOS 3.2). As usual, use it at your own risk. Enjoy! <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/" rel="bookmark" title="July 7, 2011">Useful 3rd Party Extensions to CoreTextWrapper</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2010/07/09/digital2-0/" rel="bookmark" title="July 9, 2010">digital2.0 iPad Application</a></li><li><a
href="http://akosma.com/2011/01/21/advanced-ios-4-2-training-course-zurich-february-7th-and-8th-2011-enroll-now/" rel="bookmark" title="January 21, 2011">Advanced iOS 4.2 Training Course &#8211; Zürich, February 7th and 8th 2011 &#8211; Enroll now!</a></li><li><a
href="http://akosma.com/2011/12/29/trainings-2012-advanced-ios-mobile-web-apps-and-node-js/" rel="bookmark" title="December 29, 2011">Trainings 2012: Advanced iOS, Mobile Web Apps and Node.js</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/07/08/core-text-objective-c-wrapper/feed/</wfw:commentRss> <slash:comments>31</slash:comments> </item> <item><title>Objective-C Categories as Stylesheets</title><link>http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/</link> <comments>http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/#comments</comments> <pubDate>Thu, 03 Jun 2010 15:52:24 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Tech]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Github]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[open source]]></category> <category><![CDATA[software]]></category> <category><![CDATA[style]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2496</guid> <description><![CDATA[It is very important that iPhone and iPad applications use visual styles in a coherent way. This helps users learn how to use your application faster, it helps them scan your UI for important information as quickly as possible, and it also can convey a strong marketing message; companies who want iPhone or iPad applications [...]]]></description> <content:encoded><![CDATA[<p>It is very important that iPhone and iPad applications use visual styles in a coherent way. This helps users learn how to use your application faster, it helps them scan your UI for important information as quickly as possible, and it also can convey a strong marketing message; companies who want iPhone or iPad applications often have complex visual identities, including predefined fonts and colors, and they will want their applications to match those choices.﻿</p><p>However, getting all the UI widgets to look similarly can be complex, particularly in large applications; what if your client or their designers change their minds about the font size or some background color right before shipping your project? Of course you can &#8220;search and replace&#8221; all occurrences of some color using Xcode, but you have the risk of leaving some unchanged widget somewhere. And believe me, this happens really often.</p><p>In this article I will discuss a simple approach, using Objective-C categories, to keep your styling information separated from the rest of the application, using a system that will be familiar to developers used to creating websites using CSS (Cascading Style Sheets).<span
id="more-2496"></span></p><h2>First Approach: Simple Categories</h2><p>The first, easiest approach is to create simple UIFont and UIColor categories in your application, and provide semantic descriptions of the data you want to style; for example &#8220;customerNameFont&#8221; and &#8220;companyPhoneColor&#8221; are good names. You can add as many class methods as you want to the UIFont and UIColor classes for that:</p><div><pre class="brush:objc">
@interface UIFont (YourAppName)
+ (UIFont *)customerNameFont;
+ (UIFont *)customerPhoneFont;
@end
@implementation UIFont (YourAppName)
+ (UIFont *)customerNameFont
{
    return [UIFont fontWithName:@"Helvetica" size:22.0];
}
+ (UIFont *)customerPhoneFont
{
    return [UIFont boldSystemFontOfSize:15.0];
}
@end
﻿</pre></div><p>And we provide the same treatment to the UIColor class:</p><div><pre class="brush:objc">
@interface UIColor (YourAppName)
+ (UIColor *)customerNameColor;
+ (UIColor *)customerPhoneColor;
@end
@implementation UIColor (YourAppName)
+ (UIColor *)customerNameColor
{
    return [UIColor blueColor];
}
+ (UIColor *)customerPhoneColor
{
    return [UIColor redColor];
}
@end
</pre></div><p>Then, you can use those method names in the rest of your application:</p><div><pre class="brush:objc">
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                       reuseIdentifier:CellIdentifier] autorelease];
        // And here goes the styling!
        cell.textLabel.font = [UIFont customerNameFont];
        cell.textLabel.textColor = [UIColor customerNameColor];
        cell.detailTextLabel.font = [UIFont customerPhoneFont];
        cell.detailTextLabel.textColor = [UIColor customerPhoneColor];
    }
    Customer *cust = [self.data objectAtIndex:indexPath.row];
    cell.textLabel.text = cust.name
    cell.detailTextLabel.text = cust.phone
    return cell;
}
</pre></div><p>The advantage of this simple approach is that all styles are managed from a central location, and you can change the fonts and colors of your application in a single step.</p><p>There are, however, two major disadvantages:</p><ol><li>Colors and fonts defined on their respective categories will not be available in Interface Builder, so you might have to override viewDidLoad or other methods to force the styling at a certain moment, or to set the color and font values manually, which might lead to duplicate information.</li><li>Some UI elements have support for even more styling information, like shadows or CGAffineTransform values, which cannot be handled in a simple way with this method.</li></ol><p>We need some kind of CSS for iPhone applications, and the next section provides a rudimentary approach to that problem.</p><h2>Second Approach, &#8220;Cascading Style&#8221; Classes</h2><p>Let&#8217;s push the idea of semantic styling a bit; in the previous example, we created separated categories for UIFont and UIColor and used them in atomic form, changing individual properties of your widgets, one by one.</p><p>What if you wanted to set several properties at once, just like with CSS classes on web pages? What if you had a system which could be extended to support more properties, for other, as of yet unknown, future UI widgets? For that, we would need a special container for style information, like a CSS stylesheet, and we should be able to assign this container to any kind of visual widget; in turn, those widgets would automatically adapt their layout and appearance. There are many different ways to do this; and this is just one of them.</p><p>First I declare a class called AKCascadingStyle, which holds basic styling information, and which is able to apply that information to any kind of object passed in parameter:</p><div><pre class="brush:objc">
@interface AKCascadingStyle : NSObject
{
@private
    UIFont *_font;
    UIColor *_textColor;
    UIColor *_backgroundColor;
    UIColor *_tintColor;
}
@property (nonatomic, retain) UIFont *font;
@property (nonatomic, retain) UIColor *textColor;
@property (nonatomic, retain) UIColor *backgroundColor;
@property (nonatomic, retain) UIColor *tintColor;
+ (id)style;
+ (id)styleFromObject:(id)object;
- (void)applyToObject:(id)object;
- (void)setValuesFromObject:(id)object;
@end
</pre></div><p>This class can be inherited and extended, and its methods can be overridden, as we&#8217;ll see shortly, to add support for more properties. Then I add a category on NSObject (careful with this!) to support adding and retrieving style information in the form of AKCascadingStyle instances:</p><div><pre class="brush:objc">
@class AKCascadingStyle;
@interface NSObject (AKCascadingStyle)
@property (nonatomic, retain) AKCascadingStyle *cascadingStyle;
@end
</pre></div><p>Why a category on NSObject? Because not everything you see on your iPhone screen is a subclass of UIView! UIBarButtonItems, for example, inherit from UIBarItem, which itself inherits from NSObject, and not from UIView. By the way, by extending NSObject, this code could also be used in Mac OS X applications, for example, without modification.</p><p>Given that categories cannot add ivars to existing classes, the getter of this property will call the [AKCascadingStyle styleFromObject:] method above:</p><div><pre class="brush:objc">
@implementation NSObject (AKCascadingStyle)
@dynamic cascadingStyle;
- (void)setCascadingStyle:(AKCascadingStyle *)style
{
    [style applyToObject:self];
}
- (id)cascadingStyle
{
    return [AKCascadingStyle styleFromObject:self];
}
@end
</pre></div><p>Both [AKCascadingStyle applyToObject:] and [AKCascadingStyle styleFromObject:] are polymorphic (as all Objective-C methods are) so subclasses can extend their functionality as required (but don&#8217;t forget to send the same message to &#8220;super&#8221; before!):</p><div><pre class="brush:objc">
@interface ShadowStyle : AKCascadingStyle
{
@private
    CGSize _shadowOffset;
    UIColor *_shadowColor;
}
@property (nonatomic) CGSize shadowOffset;
@property (nonatomic, retain) UIColor *shadowColor;
@end
</pre></div><p>Then, to use these style classes in your own controllers, just do the following:</p><div><pre class="brush:objc">
- (IBAction)addStyle:(id)sender
{
    self.contentsTextView.cascadingStyle = [ShadowStyle style];
}
</pre></div><p>Setting this property will automatically set all the required parameters in your widget; text color, background colors, transformations, you name it. You can inherit styles in order to reuse them, and you can style pretty much any kind of UIKit widget with it.</p><p>You can <a
target="_blank" href="http://github.com/akosma/AKCascadingStyle">download the code of this project from Github</a>, as usual! Enjoy! <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/" rel="bookmark" title="January 31, 2012">Determining Delegate Object Method Call Order in Objective-C with NSProxy</a></li><li><a
href="http://akosma.com/2011/03/28/smart-pointers-in-objective-c/" rel="bookmark" title="March 28, 2011">Smart Pointers in Objective-C++</a></li><li><a
href="http://akosma.com/2011/01/21/advanced-ios-4-2-training-course-zurich-february-7th-and-8th-2011-enroll-now/" rel="bookmark" title="January 21, 2011">Advanced iOS 4.2 Training Course &#8211; Zürich, February 7th and 8th 2011 &#8211; Enroll now!</a></li><li><a
href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/" rel="bookmark" title="October 11, 2010">How knowing C and C++ can help you write better iPhone apps, part 1</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>initWithContentsOfURL: Methods Considered Harmful</title><link>http://akosma.com/2010/05/28/initwithcontentsofurl-methods-considered-harmful/</link> <comments>http://akosma.com/2010/05/28/initwithcontentsofurl-methods-considered-harmful/#comments</comments> <pubDate>Fri, 28 May 2010 16:45:59 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Opinion]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[asynchronous]]></category> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Network]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[synchronous]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2486</guid> <description><![CDATA[As I promised on Twitter, here&#8217;s a small discussion about the problems brought by the &#8220;initWithContentsOfURL:&#8221; family of methods. A quick search in the Xcode documentation browser brings in an interesting list of classes including this initializer (with or without additional parameters): NSArray NSManagedObjectModel NSData NSDictionary NSXMLParser NSMappingModel NSString AVAudioPlayer Don&#8217;t get me wrong, the [...]]]></description> <content:encoded><![CDATA[<p>As I <a
target="_blank" href="http://twitter.com/akosma/status/14715706200">promised on Twitter</a>, here&#8217;s a small discussion about the problems brought by the &#8220;initWithContentsOfURL:&#8221; family of methods.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2009/12/3709438002_021cb145181.jpg" alt="3709438002_021cb14518.jpg" border="0" width="170" height="255" class="alignleft size-full" /></p><p>A quick search in the Xcode documentation browser brings in an interesting list of classes including this initializer (with or without additional parameters):</p><ul><li>NSArray</li><li>NSManagedObjectModel</li><li>NSData</li><li>NSDictionary</li><li>NSXMLParser</li><li>NSMappingModel</li><li>NSString</li><li>AVAudioPlayer</li></ul><p>Don&#8217;t get me wrong, the title of this post is a bit misleading; it&#8217;s not that this method is always problematic, particularly when the URL passed as parameter has been built using the fileURLWithPath: family of initializers. In this case, the URL will point to a local resource, and the worst thing that can happen in that case is that the filename is wrong, or that the file does not exist for some reason (NSFileManager to the rescue!).</p><p>However, when using external URLs referencing resources somewhere over the network, <strong>using this method is definitely a recipe for disaster.</strong></p><p><span
id="more-2486"></span> The main problem with these methods, of course, is the fact that they are <strong>synchronous</strong>; this means that the thread executing them (usually the UI thread) will block completely until they return, and in most applications this means that you are de-facto blocking the whole application for an unknown amount of time. This means that no buttons or UI widgets will react to input, no navigation will be possible, no touch events will be delivered or executed, nothing will happen at all until the network operation completes.</p><p>Even worse; when using initWithContentsOfURL:, there is no timeout, there is no meaningful feedback for network failures, and no way for the user to cancel the current network operation. This last factor justifies by itself not using initWithContentsOfURL: at all; you must never ship code that leads to a bad user experience. Your users will resent this and will complain!</p><p>As Joel Spolsky explained in his classic article <a
target="_blank" href="http://www.joelonsoftware.com/articles/fog0000000041.html">Three Wrong Ideas From Computer Science</a>,</p><blockquote>One example of network transparency is the famous RPC (remote procedure call), a system designed so that you can call procedures (subroutines) running on another computer on the network exactly as if they were running on the local computer. An awful lot of energy went into this. Another example, built on top of RPC, is Microsoft&#8217;s Distributed COM (DCOM), in which you can access objects running on another computer as if they were on the current computer.
Sounds logical, right?
Wrong.
There are three very major differences between accessing resources on another machine and accessing resources on the local machine:<ol><li>Availability,</li><li>Latency, and</li><li>Reliability.</li></ol></blockquote><p>(BTW, read this article, it&#8217;s really a good one, like many others in his blog)</p><p>In summary, never assume that the network is available, never assume that anything behind the network is available, and never assume that a network has any particular speed. This is particularly true in the case of mobile platforms, where network conditions can vary tremendously from one minute to the other!</p><p>The problem with the initWithContentsOfURL: methods is that some online tutorials use them as a quick-and-dirty way to load resources from the network (for <a
target="_blank" href="http://icodeblog.com/2009/06/19/using-nsxmlparser-to-pull-uiimages-from-the-web/">example this one on iCodeBlog</a>), and I have myself seen production code using this method.</p><p><strong>This is very, very bad.</strong> Using initWithContentsOfURL: with remote network resources in a tutorial like this is simply a horrendous, almost irresponsible approach towards developers new to the iPhone platform.</p><p>You must not use synchronous connections in any way in your code, unless you are 100% sure that you are running it in a non-UI thread &#8211; and even so, as <a
target="_blank" href="http://iphonedevelopment.blogspot.com/2010/05/downloading-images-for-table-without.html">Jeff LaMarche explained recently</a>, you should avoid such multithreaded approaches. The NSRunLoop architecture of Cocoa and Cocoa touch allows you to bypass threading altogether when dealing with networking operations. Remember this! And read Jeff&#8217;s article for more details.</p><p>This exact same problem can also be created with other APIs and libraries, for example when using NSURLConnection&#8217;s sendSynchronousRequest:returningResponse:error: method (as explained <a
target="_blank" href="http://theappleblog.com/2010/05/28/iphone-dev-sessions-responsive-web-enabled-iphone-apps/?utm_source=feedburner&#038;utm_medium=feed&#038;utm_campaign=Feed%3A+TheAppleBlog+%28TheAppleBlog%29">today in The Apple Blog</a>.)</p><p><strong>Do not block the main UI thread.</strong> Write this on your whiteboard, on a post-it on your computer monitor, in your agenda with a reminder every day. Do not use this approach. <a
target="_blank" href="http://twitter.com/0xced/status/14717929660">As Cédric said</a>, these methods should only be used for prototyping!</p><p>One popular example of a network library that support asynchronous connections is <a
target="_blank" href="http://allseeing-i.com/ASIHTTPRequest/">ASIHTTPRequest</a>, which I tend to use in nearly all my projects (instead of the standard NSURLConnection classes bundled in Cocoa and Cocoa Touch.) I prefer it because it has a nicer, smaller interface, it&#8217;s fast (I&#8217;ve benchmarked it in my <a
target="_blank" href="http://github.com/akosma/iPhoneWebServicesClient">iPhone Web Services Client</a> demo project on Github), and it provides handy queueing capabilities. FTW!</p><p>By the way, Ben Copsey (the creator of ASIHTTPRequest) <a
target="_blank" href="http://allseeing-i.com/A-possible-replacement-for-ASINetworkQueue">has published today an article in his blog</a>, in which he exposes the approaches used to queue network connections in his library. Designing a library for concurrent, queued network connections is not trivial, and his current approach (subclassing NSOperationQueue) might soon be deprecated for a new, NSRunLoop-y, more Cocoa-friendly, way.</p><p>In any case, I hope I have made my point: avoid synchronous operations when loading content from the network, remember what Joel said, and use a library providing asynchronous connections. Happy coding!</p><p>PS: by the way, the title of this blog post is a reference to many other classic articles, so many that there&#8217;s even a <a
href="http://en.wikipedia.org/wiki/Considered_harmful" target="_blank">Wikipedia entry about them</a> and a <a
href="http://meyerweb.com/eric/comment/chech.html" target="_blank">great rant about them</a> by Eric Meyer! <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/" rel="bookmark" title="October 11, 2010">How knowing C and C++ can help you write better iPhone apps, part 1</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2010/02/10/iphone-dev-day-in-geneva-on-april-28th/" rel="bookmark" title="February 10, 2010">iPhone Dev Day in Geneva on April 28th</a></li><li><a
href="http://akosma.com/2010/02/17/the-dawn-of-couch-computing/" rel="bookmark" title="February 17, 2010">The Dawn of Couch Computing</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/05/28/initwithcontentsofurl-methods-considered-harmful/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- Dynamic page generated in 1.379 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-06 21:01:09 -->

