<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;C0YDQHYzeip7ImA9WxJVGUo.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800</id><updated>2009-07-07T05:52:51.882-07:00</updated><title>Cocoa with Love</title><subtitle type="html">Advanced programming tips, tricks and hacks for Mac development in C/Objective-C and Cocoa.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://cocoawithlove.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>74</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/CocoaWithLove" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;C0YDQHYzcSp7ImA9WxJVGUo.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-7810400073000492476</id><published>2009-07-06T03:41:00.001-07:00</published><updated>2009-07-07T05:52:51.889-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-07T05:52:51.889-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><title>HashValue: an object for holding MD5 and SHA hashes</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Hash values are small, convenient values that you can generate from larger blocks of data for easy indexing, sorting and tracking. The traditional approach for generating MD5 and SHA hashes on Unix platforms to is to use command-line programs like openssl and md5. Apple provide easier approaches in the CommonCrypto library: here's how to use it, along with an NSValue subclass to wrap the result for interoperability with other Cocoa classes.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Introduction to hashes&lt;/h4&gt;
&lt;p&gt;A hash value is a small, convenient number used to track or sort an arbitrary block of data.&lt;/p&gt;

&lt;p&gt;A real-world example of a hash value is the initial letter in a word. You can use the initial letter of a word to lookup that word in a dictionary. If two words have different starting letters, they cannot be equal but if two words have the same starting letter, that doesn't guarantee they are the same.&lt;/p&gt;

&lt;p&gt;For fast searching, you can immediately see the problem with only using an initial letter: if all you had to look up a word was its initial letter, you'd still have thousands of words to go through that all start with the same letter. You could use the first four letters but some combinations will be rare (like "aard") but others will contain hundreds of matches (like "stra").&lt;/p&gt;

&lt;p&gt;In computing, we rarely ever use the first values in a block of data to track that block of data. Starting values of blocks of data are too often the same or similar &amp;mdash; especially in the common case where we are sorting data that already has traits in common.&lt;/p&gt;

&lt;p&gt;Instead, we use hash functions that use relatively complex mathematics to generate values from the source data that are well spread, even for source data that is nearly identical. Fortunately, you don't need to know the underlying mathematics, all you need to know is that a hash value can be used to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;check if two blocks of data are the same&lt;/li&gt;
&lt;li&gt;sort data into hash tables&lt;/li&gt;
&lt;li&gt;checksum data (make certain your data hasn't changed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though these are the main purposes for which you should use hashes, MD5 and SHA hashes were actually developed for cryptography, not basic data handling. Nevertheless, for encryption and password handling in your own applications, I recommend using the Keychain (Security.framework) rather than manually using cryptographic hashes.&lt;/p&gt;

&lt;h4&gt;Generating an MD5&lt;/h4&gt;

&lt;p&gt;MD5 is one of the most common hash functions. While it is no longer considered safe for security, its use as a checksum is very common.&lt;/p&gt;

&lt;p&gt;The traditional Unix approach is to use the md5 program on the command-line:&lt;/p&gt;

&lt;pre&gt;matt$ md5 -s "Some data value."
MD5 ("Some data value.") = db7116c8634ad7fe3bd90bee94274ee0&lt;/pre&gt;

&lt;p&gt;The 32 character hexadecimal string is a human readable representation of the 16 byte output of the MD5 function.&lt;/p&gt;

&lt;p&gt;On the Mac and iPhone, we can generate this value as follows:&lt;/p&gt;

&lt;pre&gt;#import &amp;lt;CommonCrypto/CommonDigest.h&amp;gt;

char input[] = "Some data value.";
char result[16];
CC_MD5(input, strlen(input), result);&lt;/pre&gt;

&lt;p&gt;However, we frequently want the human-readable hexadecimal string. The following will produce an identical ouput to the previous command-line invocation:&lt;/p&gt;

&lt;pre&gt;printf("MD5 (\"%s\") = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
    input,
    result[0], result[1], result[2], result[3], 
    result[4], result[5], result[6], result[7],
    result[8], result[9], result[10], result[11],
    result[12], result[13], result[14], result[15]);&lt;/pre&gt;

&lt;p&gt;Producing other kinds of hash works in the same way. e.g. For SHA256, use &lt;code&gt;CC_SHA256&lt;/code&gt; instead of &lt;code&gt;CC_MD5&lt;/code&gt; and increase the size of the result to 20 from 16.&lt;/p&gt;

&lt;h4&gt;The HashValue class&lt;/h4&gt;

&lt;p&gt;Since hash values are frequently used to track blocks of data in a program, it would be nice to have an Objective-C class that wraps the hash values so we can use them in &lt;code&gt;NSDictionary&lt;/code&gt; objects as keys for our data.&lt;/p&gt;

&lt;p&gt;If we consider a hash value simply as a small C struct, i.e:&lt;/p&gt;

&lt;pre&gt;typedef struct
{
    char value[CC_MD5_DIGEST_LENGTH];
} HashValueMD5Hash;

typedef struct
{
    char value[CC_SHA256_DIGEST_LENGTH];
} HashValueShaHash;&lt;/pre&gt;

&lt;p&gt;then the easiest way to make it a fully fledged Objective-C object is to create an &lt;code&gt;NSValue&lt;/code&gt; from it:&lt;/p&gt;

&lt;pre&gt;char input[] = "Some data value.";
HashValueMD5Hash result;
CC_MD5(input, strlen(input), &amp;result);

NSValue *myHashValue = [NSValue valueWithBytes:&amp;result objCType:@encode(HashValueMD5Hash)];&lt;/pre&gt;

&lt;p&gt;That's an okay solution but if you're generating a lot of hashes in your program, it would be good to have a class that:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;has an optimized construction method that can generate the hash directly from &lt;code&gt;NSData&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;abstracts away the C struct so you can deal exclusively with the Objective-C objects&lt;/li&gt;
&lt;li&gt;overrides the &lt;code&gt;description&lt;/code&gt; method to easily generate human-readable strings&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So I wrote the &lt;code&gt;HashValue&lt;/code&gt; class.&lt;/p&gt;

&lt;pre&gt;@interface HashValue : NSObject &amp;lt;NSCoding, NSCopying&amp;gt;
{
    unsigned char value[HASH_VALUE_STORAGE_SIZE];
    HashValueType type;
}

- (id)initMD5HashWithBytes:(const void *)bytes length:(NSUInteger)length;
+ (HashValue *)md5HashWithData:(NSData *)data;
- (id)initSha256HashWithBytes:(const void *)bytes length:(NSUInteger)length;
+ (HashValue *)sha256HashWithData:(NSData *)data;

- (const void *)value;
- (HashValueType)type;

@end&lt;/pre&gt;

&lt;p&gt;Despite being a class that wraps a value, there's no explicit reason to make it a subclass of &lt;code&gt;NSValue&lt;/code&gt;. Since subclassing &lt;code&gt;NSValue&lt;/code&gt; has inherent difficulties (you need to carefully override a lot of inherited methods) I've made the class a basic subclass of &lt;code&gt;NSObject&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;init&lt;/code&gt; method implementations are fairly simple:&lt;/p&gt;

&lt;pre&gt;- (id)initMD5HashWithBytes:(const void *)bytes length:(NSUInteger)length
{
    self = [super init];
    if (self != nil)
    {
        CC_MD5(bytes, length, value);
        type = HASH_VALUE_MD5_TYPE;
    }
    return self;
}&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;description&lt;/code&gt; method is overridden to provide the human-readable hexadecimal string:&lt;/p&gt;

&lt;pre&gt;- (NSString *)description
{
    NSInteger byteLength;
    if (type == HASH_VALUE_MD5_TYPE)
    {
        byteLength = sizeof(HashValueMD5Hash);
    }
    else if (type == HASH_VALUE_SHA_TYPE)
    {
        byteLength = sizeof(HashValueShaHash);
    }

    NSMutableString *stringValue =
        [NSMutableString stringWithCapacity:byteLength * 2];
    NSInteger i;
    for (i = 0; i &lt; byteLength; i++)
    {
        [stringValue appendFormat:@"%02x", value[i]];
    }
    
    return stringValue;
}&lt;/pre&gt;

&lt;p&gt;Most of the other methods in the class are basic accessors or &lt;code&gt;NSCopying&lt;/code&gt;, &lt;code&gt;NSCoding&lt;/code&gt; and &lt;code&gt;NSObject&lt;/code&gt; methods. The copying methods in particular are essential so that the object can be used as a key in an &lt;code&gt;NSDictionary&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will highlight one other method:&lt;/p&gt;

&lt;pre&gt;- (NSUInteger)hash
{
    return *((NSUInteger *)value);
}&lt;/pre&gt;

&lt;p&gt;You may wonder why it's necessary to have a hash method on a class that is itself a hash value. Hash methods in Cocoa are used for the same indexing and sorting tasks I identified above: sorting and finding objects in &lt;code&gt;NSSet&lt;/code&gt; and &lt;code&gt;NSDictionary&lt;/code&gt;. In Cocoa the default &lt;code&gt;hash&lt;/code&gt; method calculates its hash value from the memory address of the object. Because we have overridden &lt;code&gt;isEqual:&lt;/code&gt; to compare the object's internal &lt;code&gt;value&lt;/code&gt;, we also need to override the &lt;code&gt;hash&lt;/code&gt; method to also reflect this change. This is a basic requirement of hashes &amp;mdash; equal objects must return the same hash value (imagine the confusion if two identically spelled words were sorted to different locations in a dictionary).&lt;/p&gt;

&lt;p&gt;It may seem a little odd to simply return the first few bytes of the &lt;code&gt;value&lt;/code&gt; as our new hash (after I explained that the first few bytes is rarely the best hash) but this case is an exception to the rule: our data is already "well-spread" and every bit in our hash is as well-spread as the next.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the &lt;a href="http://projectswithlove.com/projects/HashValue.zip"&gt;HashValue class as a .zip file&lt;/a&gt; (2kB)&lt;/blockquote&gt;

&lt;p&gt;Hash values are used everywhere. Git uses SHA1 to track file changes in its repository, BitTorrent uses MD5s to identify torrents and many download programs use hashes to checksum downloaded data.&lt;/p&gt;

&lt;p&gt;The CommonCrypto library (part of Foundation on the Mac and iPhone through libSystem) makes generating common hash functions very simple.&lt;/p&gt;

&lt;p&gt;As with all data manipulation, I think a nice Cocoa class around the data makes it easier to use. I have only added MD5 and SHA256 to this particular implementation but it should be very simple to add other CommonCrypto hashes to the class should you require them.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-7810400073000492476?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/7810400073000492476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/7810400073000492476?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/07/hashvalue-object-for-holding-md5-and.html" title="HashValue: an object for holding MD5 and SHA hashes" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author></entry><entry gd:etag="W/&quot;DU8HR3o9eyp7ImA9WxJVFUU.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1329114706463822659</id><published>2009-07-02T02:23:00.001-07:00</published><updated>2009-07-02T19:23:56.463-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-02T19:23:56.463-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Xcode" /><category scheme="http://www.blogger.com/atom/ns#" term="AppKit" /><title>Custom views in Interface Builder using IBPlugins</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;If you have custom views configured in code, it can be time consuming to configure them for each instance and make them look right in context. To make the process smoother, you can create Interface Builder plugins and configure your objects in Interface Builder. While the Xcode documentation explains how to do this, it is long, thorough and confusing. Here is the simplified set of steps that I use to create Interface Builder plugins quickly.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Introduction&lt;/h4&gt;

&lt;p&gt;Apple do have extensive documentation on &lt;a href="http://developer.apple.com/documentation/developertools/Conceptual/IBPlugInGuide/Introduction/Introduction.html"&gt;Interface Builder Plugin creation&lt;/a&gt;. However, their documentation is thorough enough that may be overwhelming the first time you want to write an Interface Builder plugin.&lt;/p&gt;

&lt;p&gt;I also find the workflow in Apple's IBPluginGuide very different to my typical workflow. I think this is because I normally just want an existing class to show up in Interface Builder so I can tweak one or two attributes &amp;mdash; the processes for creating a redistributable library of components is more than I need.&lt;/p&gt;

&lt;p&gt;So I was inspired to write this post: a shorter, workflow-optimised version of the same process described in the IBPluginGuide &amp;mdash; using Interface Builder to configure a custom button.&lt;/p&gt;

&lt;h4&gt;A custom buttom&lt;/h4&gt;

&lt;p&gt;Consider the button in the following window:&lt;/p&gt;

&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/Skwv9EqkB2I/AAAAAAAAAVo/GkQcQJEHeN0/ibplugin1.png?imgmax=800" alt="ibplugin1.png" border="0" width="226" height="318" /&gt;

&lt;p style="text-align:center;"&gt;&lt;em&gt;A big, drab, gray button. Maybe gray is an acceptable default but it doesn't really match this window. This post will make it easy to adjust this color in Interface Builder.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The large gray button here uses a custom button cell which draws the button using the &lt;a href="http://cocoawithlove.com/2008/09/drawing-gloss-gradients-in-coregraphics.html"&gt;Gloss Gradient from one of my earlier posts&lt;/a&gt;. The drawing code is:&lt;/p&gt;

&lt;pre&gt;- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    NSBezierPath *roundRectPath =
        [NSBezierPath
            bezierPathWithRoundedRect:NSInsetRect(cellFrame, 2, 2)
            xRadius:5
            yRadius:5];

    NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
    [graphicsContext saveGraphicsState];
    [roundRectPath addClip];

    DrawGlossGradient(
        [graphicsContext graphicsPort],
        &lt;strong&gt;self.buttonColor&lt;/strong&gt;, // &lt;-- this determines the color of the button
        cellFrame);

    if ([self isHighlighted])
    {
        [[NSColor colorWithCalibratedRed:0.0 green:0.15 blue:0.35 alpha:0.5]
            set];
        [roundRectPath fill];
    }
    [graphicsContext restoreGraphicsState];

    [[NSColor lightGrayColor] set];
    [roundRectPath setLineWidth:2.0];
    [roundRectPath stroke];

    [self drawInteriorWithFrame:cellFrame inView:controlView];
}&lt;/pre&gt;

&lt;p&gt;This is all fine except that the color of the button is determined by the &lt;code&gt;self.buttonColor&lt;/code&gt; property and if we have to choose this in code (continually changing the value, fixing, continuing, refreshing and repeating) it could get very time consuming.&lt;/p&gt;

&lt;p&gt;A better solution would be to edit the button's color in Interface Builder. That way, we will be able to use color sliders to update the button drawn in the complete context of the window, in real-time.&lt;/p&gt;

&lt;h4&gt;Creating the IBPlugin project&lt;/h4&gt;

&lt;p&gt;My process normally starts by creating a custom view component. In this case, I have already created a class named &lt;code&gt;CustomButtonCell&lt;/code&gt; in the project for my main application (AppWithButton). After creating the class, I have decided it would be a good idea to have an Interface Builder Plug-In.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;A quick point about class requirements&lt;/strong&gt;: every property we want to configure in Interface Builder must be encoded and decoded for the object using implementations of the &lt;code&gt;NSCoder&lt;/code&gt; protocol methods &lt;code&gt;initWithCoder:&lt;/code&gt; and &lt;code&gt;encodedWithCoder:&lt;/code&gt; overrides. Download the project linked below to see how this is done.&lt;/blockquote&gt;

&lt;h5&gt;1. Create and name the project&lt;/h5&gt;

&lt;p&gt;"Interface Builder Plug-In" is a project template in Xcode. In the New Project window, it's in the "Mac OS X -&gt; Standard Apple Plug-ins" section.&lt;/p&gt;

&lt;p&gt;An important point to consider is the name for the project &amp;mdash; it should not be the same as the custom view component (in this case, &lt;code&gt;CustomButtonCell&lt;/code&gt;) because the template will create a class with the name and it can't conflict with the existing view component.&lt;/p&gt;

&lt;p&gt;I chose "ButtonPlugin" and saved the new project in the folder for my existing AppWithButton project.&lt;/p&gt;

&lt;h5&gt;2. Make the new project use the existing CustomButtonCell&lt;/h5&gt;

&lt;h6&gt;Delete the default files and insert our own&lt;/h6&gt;

&lt;p&gt;The template creates a custom view in the ButtonPlugin project. I never use this (since I want to use my existing view). So I delete the ButtonPluginView.m, ButtonPluginView.h references and files.&lt;/p&gt;

&lt;p&gt;I add my CustomButtonCell.m and CustomButtonCell.h files to the ButtonPlugin project but I don't copy or move the files &amp;mdash; I leave the files at their current locations in AppWithButton project but drag them into the ButtonPlugin's Source Tree.&lt;/p&gt;

&lt;h6&gt;Make certain these new files get built&lt;/h6&gt;

&lt;p&gt;You need to check that the CustomButtonCell.m is added to the Compile Sources build phase of the ButtonPluginFramework Target and the CustomButtonCell.h is added to the Copy Headers build phase of the ButtonPluginFramework. Neither should appear in the ButtonPlugin target.&lt;/p&gt;

&lt;p&gt;Then, select the "CustomButtonCell.h" file from the "Copy Headers" build phase and in the Detail View, change the "Role" from "Project" to "Public". This is a pretty obscure thing to do. I normally don't have the Detail View visible &amp;mdash; if you don't know which view is the Detail View, it's time to learn because there is no other way to change this value in Xcode.&lt;/p&gt;

&lt;img src="http://lh6.ggpht.com/_gfktUGS0ov0/SkxgFIoJy4I/AAAAAAAAAVw/Dzss2-hxUy8/ibplugin3.png?imgmax=800" alt="ibplugin3.png" border="0" width="519" height="313" /&gt;
&lt;p style="text-align:center;"&gt;&lt;em&gt;Change the Role of the "CustomButtonCell.h" to "public" in the Detail View&lt;/em&gt;&lt;p&gt;

&lt;p&gt;Rename the file ButtonPluginViewIntegration.m to CustomButtonCellIntegration.m and replace every occurrence of ButtonPluginView in this file to CustomButtonCell.&lt;/p&gt;

&lt;h5&gt;3. Prepare all the other files in the project&lt;/h5&gt;

&lt;p&gt;Make the following file changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the ButtonPluginView.classdescription and rename this file to CustomButtonCell.classdecription (same as our custom cell).&lt;/li&gt;
&lt;li&gt;In the contents of this file, change the &lt;code&gt;ClassName&lt;/code&gt; to match the actual class name &lt;code&gt;CustomButtonCell&lt;/code&gt; and change the &lt;code&gt;SuperClass&lt;/code&gt; to be &lt;code&gt;NSButtonCell&lt;/code&gt; (again, matching the actual super class for our custom button cell).&lt;/li&gt;
&lt;li&gt;In ButtonPlugin.m (the top level class in the ButtonPlugin project), set the bundle identifier to something appropriate. I used &lt;code&gt;com.mattgallagher.ButtonPlugin&lt;/code&gt; &amp;mdash; this needs to be unique among Interface Builder plugins, so you pick an appropriate value each time.&lt;/li&gt;
&lt;li&gt;Set the bundle identifier in the Info.plist and the ButtonPlugin-Info.plist to the same &lt;code&gt;com.mattgallagher.ButtonPlugin&lt;/code&gt; value.&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;4. Configure the display of the button cell for the Interface Builder Library panel&lt;/h5&gt;

&lt;p&gt;Open the ButtonPluginLibrary.nib. This file contains the "Library Object Template" view (an instance of IBLibraryObjectTemplate). You can find it in the "Library Objects" view at the top level.&lt;/p&gt;

&lt;h6&gt;Delete the library template that doesn't apply&lt;/h6&gt;

&lt;p&gt;The Library Object Template will contain a "Template" and an "Example" square. The "Template" version is for &lt;code&gt;NSView&lt;/code&gt; subclasses but our &lt;code&gt;CustomButtonCell&lt;/code&gt; needs to be embedded in another object (an &lt;code&gt;NSButton&lt;/code&gt;) so we will use the "Example" square &amp;mdash; so delete the "Template" square.&lt;/p&gt;

&lt;h6&gt;Set our custom class in the library template&lt;/h6&gt;

&lt;p&gt;If you click on the button in the "Example" square then click again, it will select the &lt;code&gt;NSButtonCell&lt;/code&gt; inside the button (these clicks should be slower than a double-click, since a double-click will edit the text of the &lt;code&gt;NSButton&lt;/code&gt; instead of selecting the &lt;code&gt;NSButtonCell&lt;/code&gt; inside). With the &lt;code&gt;NSButtonCell&lt;/code&gt; selected:

&lt;ol&gt;
&lt;li&gt;Type Command-6 to select the correct inspector panel.&lt;/li&gt;
&lt;li&gt;Enter the custom class name in the "Class" field of the inspector &amp;mdash; in our case, we need this to be &lt;code&gt;CustomButtonCell&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the button cell class for the &lt;code&gt;NSButton&lt;/code&gt; to the right of the "Example" box in the same way.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Select the Library Object Template (ButtonPluginLibrary.nib window -&gt; Library Objects -&gt; Library Object Template) and:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type Command-1 to select the correct inspector panel.&lt;/li&gt;
&lt;li&gt;Fill in the "Label", "Summary" and "Description" for your Library Object as you choose. I like to delete the Path and leave it blank but you can add a path if you want to categorize your custom classes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;5. Configure the Interface Builder Inspector panel&lt;/h5&gt;

&lt;p&gt;Back in the ButtonPlugin project again, open the ButtonPluginInspector.xib.&lt;/p&gt;

&lt;h6&gt;Set all the controls in the Inspector panel how we want them&lt;/h6&gt;

&lt;p&gt;I deleted everything in the "Inspector View" window except 1 label and the &lt;code&gt;NSColorWell&lt;/code&gt;. I moved these controls to the top of the view and then made the view 35 pixels high.&lt;/p&gt;

&lt;h6&gt;Connect the controls so they act on our object&lt;/h6&gt;

&lt;p&gt;To make the color selector do something, I used bindings. Select the &lt;code&gt;NSColorWell&lt;/code&gt; and:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type Command-4 to select the correct inspector panel.&lt;/li&gt;
&lt;li&gt;Under the "Value" subheading, bind to File's Owner (make sure the checkbox is selected too).&lt;/li&gt;
&lt;li&gt;Set the Model Key Path to &lt;code&gt;inspectedObjectsController.selection.buttonColor&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This binding needs one other change to work. Back in the ButtonPlugin project, open the CustomButtonCellIntegration.m file. Change the &lt;code&gt;[[keyPaths objectForKey:IBAttributeKeyPaths&lt;/code&gt;... line to:&lt;/p&gt;

&lt;pre&gt;[[keyPaths objectForKey:IBAttributeKeyPaths]
    addObjectsFromArray:[NSArray arrayWithObjects:@"buttonColor", nil]];&lt;/pre&gt;

&lt;p&gt;This tells Interface Builder to track and monitor the &lt;code&gt;buttonColor&lt;/code&gt; property on the &lt;code&gt;CustomButtonCell&lt;/code&gt; class. It does not actually perform the value changing (the binding we established will change the value directly) but it will make certain that this value will be tracked for undos and can be edited correctly.&lt;/p&gt;

&lt;h4&gt;Using the IBPlugin&lt;/h4&gt;

&lt;p&gt;At this point, you can run the ButtonPlugin project and it will launch Interface Builder with the plugin visible. The only problem is that the plugin won't be visible if you launch Interface Builder in any other way.&lt;/p&gt;

&lt;h5&gt;Build Settings&lt;/h5&gt;

&lt;p&gt;The following steps will make the ButtonPlugin project build the ButtonPlugin.framework and ButtonPlugin.ibplugin and install it in your Library.&lt;/p&gt;

&lt;p&gt;Double click the ButtonPlugin project item in the ButtonPlugin project Source Tree to edit the project settings. Select the "Build" tab, then choose "Configuration: All Configurations". Then make the following changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set the "Deployment Location" checkbox to checked.&lt;/li&gt;
&lt;li&gt;Set the "Installation Build Products Location" to "$(HOME)/Library/Frameworks".&lt;/li&gt;
&lt;li&gt;Set the "Installation Directory" to "/".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Double-click the "ButtonPlugin" target in the Source Tree to edit that target's settings. Select the "Build" tab, then choose "Configuration: All Configurations". Then make the following change:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Set the "Installation Directory" to "/ButtonPlugin.framework/Resources.&lt;/li&gt;&lt;/ol&gt;

&lt;h5&gt;And now it's installed&lt;/h5&gt;

&lt;p&gt;With these changes made, build and run the ButtonPlugin project and it will install the ButtonPlugin.framework in your ~/Library/Frameworks directory and load it in Interface Builder. From now until you remove the framework from your library, it will remain in Interface Builder and you can use it at any time.&lt;/p&gt;

&lt;p&gt;I realize that this configures the app to install the "Debug" build in the user's library, over the top of the "Release" build (if the Release build is already built) but this is really just for local use, so I don't really care. If you do care, you might not want to apply these settings to all configurations. For me: this is faster to implement and easier to manage.&lt;/p&gt;

&lt;h4&gt;Integration with the original AppWithButton project&lt;/h4&gt;

&lt;p&gt;After setting up the Interface Builder plugin, instance of CustomButtonCell in your existing .xib and .nib files will not instantly update. You'll probably need to create new versions of the cell by dragging them out from the Library.&lt;/p&gt; 

&lt;p&gt;In this example, I have chosen to not link the original AppWithButton project with the ButtonPlugin.framework. This is because I don't want to distribute either the framework or the plugin &amp;mdash; they are both for my purposes only.&lt;/p&gt;

&lt;p&gt;If you wanted to link them, you could remove the CustomButtonCell.m and CustomButtonCell.h files from the original project and replace them with the ButtonPlugin.framework. According to the Xcode documentation, this arrangement would allow you to avoid installing the ButtonPlugin.framework in your ~/Library/Frameworks directory (Interface Builder would automatically find the plugin for any .nib or .xib file in the project). That's a nice idea but it has never worked for me, so I never bother.&lt;/p&gt;

&lt;h6&gt;Set a build dependency to keep ButtonPlugin up-to-date&lt;/h6&gt;

&lt;p&gt;Instead, I like to drag the ButtonPlugin.xcodeproj file into the AppWithButton Source Tree and edit the AppWithButton target, go to the "General" tab and add the ButtonPlugin.xcodeproj as a Direct Dependency.&lt;/p&gt;

&lt;p&gt;The reason for this is that if I change the CustomButtonCell class and rebuild, it will automatically rebuild the Interface Builder plugin accordingly (you need to restart Interface Builder to see the changes).&lt;/p&gt;

&lt;img src="http://lh6.ggpht.com/_gfktUGS0ov0/SkxejRb45dI/AAAAAAAAAVs/_QEbecxLgvI/ibplugin2.png?imgmax=800" alt="ibplugin2.png" border="0" width="538" height="280" /&gt;

&lt;p style="text-align:center;"&gt;&lt;em&gt;The AppWithButton window in Interface Builder, adjusting the color of the button in real-time.&lt;/em&gt;&lt;p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the complete &lt;a href="http://projectswithlove.com/projects/AppWithButton.zip"&gt;AppWithButton project zip file (including the ButtonPlugin project)&lt;/a&gt; (385kB).&lt;/blockquote&gt;

&lt;p&gt;It takes quite a few steps to set up an Interface Builder plugin. Fortunately, they're all simple, if a little menial.&lt;/p&gt;

&lt;p&gt;Notice how little code was actually written though: bindings and Objective-C 2.0 properties make this whole process considerably easier &amp;mdash; there is no actual code written to set the &lt;code&gt;buttonColor&lt;/code&gt; (except in the &lt;code&gt;NSCoder&lt;/code&gt; method implementations) since the bindings do it all for us.&lt;/p&gt;

&lt;p&gt;Once you're practiced at making plugins in this way, the effort to create one may be justified, even just to tweak simple properties like this.&lt;/p&gt;

&lt;p&gt;Do I know how to do this for Cocoa Touch classes for iPhone development? No. I imagine it's possible but you'd need to completely change the IBPlugin project from the template and I've never tried.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1329114706463822659?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1329114706463822659?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1329114706463822659?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/07/custom-views-in-interface-builder-using.html" title="Custom views in Interface Builder using IBPlugins" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author></entry><entry gd:etag="W/&quot;CkIFR3s7fSp7ImA9WxJWF0s.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-3272576292203531801</id><published>2009-06-23T05:33:00.001-07:00</published><updated>2009-06-23T05:35:16.505-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-23T05:35:16.505-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><title>Verifying that a string contains an email address using NSPredicate</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;To celebrate the official release of iPhone OS 3.0 this week, I will show you how to verify that an NSString contains a syntactically valid email address using NSPredicate &amp;mdash; a class that joins the iPhone SDK 3.0 as part of the Core Data additions. This code will work on Mac OS X too since, as with the rest of Core Data, NSPredicate has been part of Mac OS X since 10.4 (Tiger).&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Before I begin...&lt;/h4&gt;
&lt;p&gt;I gave an interview to Anthony Agius of &lt;a href="http://www.mactalk.com.au"&gt;MacTalk.com.au&lt;/a&gt; this week. You can &lt;a href="http://www.mactalk.com.au/2009/06/23/mactalk-interviews-10-matt-gallagher-cocoa-with-love/"&gt;download the MP3 from their website&lt;/a&gt;. I'm hesitant to listen to my own voice but I think I talked about what it's like to be an independent Mac/iPhone developer in Melbourne, Australia.&lt;/p&gt;

&lt;h4&gt;Back to predicates&lt;/h4&gt;
&lt;p&gt;In programming, a predicate is a condition that returns true or false if the object it processes has the properties that the predicate describes. The key difference between a predicate and a regular boolean expression is that a predicate only considers the properties of one object, where a boolean expression may consider multiple, unrelated objects.&lt;/p&gt;

&lt;p&gt;Many programmers are familiar with predicates as used in SQL database queries. For example a query to extract the complete row from the "people" database table for every person named "John Smith" might look like this in SQL:&lt;/p&gt;

&lt;pre&gt;SELECT * FROM people WHERE firstname = 'John' AND lastname = 'Smith'&lt;/pre&gt;

&lt;p&gt;Everything after the "WHERE" is the predicate &amp;mdash; it looks at properties of the row only and is either true (the row will be extracted) or false (the row will be ignored).&lt;/p&gt;

&lt;h4&gt;Using NSPredicate to evaluate predicates&lt;/h4&gt;

&lt;p&gt;In Cocoa, &lt;code&gt;NSPredicate&lt;/code&gt; works in much the same way as the "WHERE" clause of SQL. The main reason that &lt;code&gt;NSPredicate&lt;/code&gt; is being brought to the iPhone is that &lt;code&gt;NSPredicate&lt;/code&gt; fulfils the same role in Core Data that "WHERE" clauses fulfil in SQL &amp;mdash; to allow the persistent store to fetch objects that satisfy specific criteria.&lt;/p&gt;

&lt;p&gt;Imagine we had an &lt;code&gt;NSDictionary&lt;/code&gt; created using the following method:&lt;/p&gt;

&lt;pre&gt;- (NSDictionary *)personRowWithFirstname:(NSString *)aFirstname
    lastname:(NSString *)aLastname
{
    return
        [NSDictionary dictionaryWithObjectsAndKeys:
            aFirstname, @"firstname",
            aLastname, @"lastname",
        nil];
}&lt;/pre&gt;

&lt;p&gt;we could test if a given row created by this method matched the predicate "&lt;code&gt;firstname = 'John' AND lastname = 'Smith'&lt;/code&gt;" with the following:&lt;/p&gt;

&lt;pre&gt;// given an NSDictionary created used the above method named "row"...
NSPredicate *johnSmithPredicate =
    [NSPredicate predicateWithFormat:@"firstname = 'John' AND lastname = 'Smith'"];
BOOL rowMatchesPredicate = [johnSmithPredicate evaluateWithObject:row];&lt;/pre&gt;

&lt;p&gt;The &lt;a href="http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795"&gt;string format used to construct an &lt;code&gt;NSPredicate&lt;/code&gt; in Cocoa&lt;/a&gt; is very similar to the syntax of the "WHERE" clause in SQL. You can also construct this &lt;code&gt;NSPredicate&lt;/code&gt; in code by building it from two &lt;code&gt;NSComparisonPredicate&lt;/code&gt;s and an &lt;code&gt;NSCompoundPredicate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A more common use of &lt;code&gt;NSPredicate&lt;/code&gt; is filtering &amp;mdash; extracting rows that match an &lt;code&gt;NSPredicate&lt;/code&gt; from a larger collection:&lt;/p&gt;

&lt;pre&gt;// given an NSArray of rows named "rows" and the above "johnSmithPredicate"...
NSArray *rowsMatchingPredicate = [rows filteredArrayUsingPredicate:johnSmithPredicate];&lt;/pre&gt;

&lt;p&gt;This is then more like an SQL query where we have selected matching rows from the larger table of data.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;NSPredicate&lt;/code&gt; handles filtering only. If you'd like to replicate SQL's "ORDER BY" clause, you can apply &lt;code&gt;NSSortDescriptor&lt;/code&gt; as a separate step.&lt;/blockquote&gt;

&lt;h4&gt;Verifying an email address&lt;/h4&gt;

&lt;p&gt;The "LIKE" comparison operator in &lt;code&gt;NSPredicate&lt;/code&gt; (&lt;code&gt;NSLikePredicateOperatorType&lt;/code&gt;) is commonly used as a convenient means of testing if an &lt;code&gt;NSString&lt;/code&gt; matches a Regular Expression. It's advantage over full libraries with greater options and replacement capability is that it is already in Cocoa &amp;mdash; no libraries, no linkage, no hassle.&lt;/p&gt;

&lt;p&gt;To test if an &lt;code&gt;NSString&lt;/code&gt; matches a regular expression, we can use the following code:&lt;/p&gt;

&lt;pre&gt;NSPredicate *regExPredicate =
    [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regularExpressionString];
BOOL myStringMatchesRegEx = [regExPredicate evaluateWithObject:myString];&lt;/pre&gt;

&lt;p&gt;The only question that remains is: what is a regular expression that can be used to verify that an &lt;code&gt;NSString&lt;/code&gt; contains a syntactically valid email address?&lt;/p&gt;

&lt;pre&gt;NSString *emailRegEx =
    @"(?:[a-z0-9!#$%\\&amp;'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&amp;'*+/=?\\^_`{|}"
    @"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
    @"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
    @"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
    @"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
    @"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
    @"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";&lt;/pre&gt;

&lt;p&gt;This regular expression is adapted from a version at &lt;a href="http://www.regular-expressions.info/email.html"&gt;regular-expressions.info&lt;/a&gt; and is a complete verification of RFC 2822.&lt;/p&gt;

&lt;p&gt;This adaptation involved escaping all backslashes with another backslash (otherwise the &lt;code&gt;NSString&lt;/code&gt; will try to interpret them before they are used in the Regular Expression) and escaping the ampersands (&amp;amp;) so it isn't interpreted as a Unicode escape sequence and caret (^) characters because &amp;mdash; actually I have no idea why except that the expression wouldn't parse without it.&lt;/p&gt;

&lt;p&gt;The linked &lt;a href="http://www.regular-expressions.info/email.html"&gt;regular-expressions.info&lt;/a&gt; page recommends using slightly different regular expressions that force the top-level domain to be a country code or a known top-level domain. With the number of top-level domains due to increase in the near future, I'm not sure this is a good constraint to impose &amp;mdash; since this check isn't intended to verify that the provided domain name is valid.&lt;/p&gt;

&lt;p&gt;Since this regular expression &lt;code&gt;NSString&lt;/code&gt; is so long, I've split it over 7 lines. This is an underused feature in Standard C languages &amp;mdash; if you split a string into pieces but put nothing except whitespace between the pieces, the compiler will treat it as one continuous string. You don't need to write an extremely long string on a single long line.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;Just a few lines of code this week but I thought it would be good to draw attention to one of the minor additions making its way to the iPhone in SDK 3.0. I use &lt;code&gt;NSPredicate&lt;/code&gt; all the time on Mac OS to perform searches, extract subarrays and perform quick Regular Expression tests. Without it, the only alternatives on the iPhone were methodical array iterations and manual comparisons in code.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-3272576292203531801?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/3272576292203531801?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/3272576292203531801?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/06/verifying-that-string-is-email-address.html" title="Verifying that a string contains an email address using NSPredicate" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author></entry><entry gd:etag="W/&quot;A0IASHg6fSp7ImA9WxJWFEg.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1227978711636506887</id><published>2009-06-17T00:39:00.001-07:00</published><updated>2009-06-19T17:59:09.615-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-19T17:59:09.615-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CoreAudio" /><category scheme="http://www.blogger.com/atom/ns#" term="UIKit" /><category scheme="http://www.blogger.com/atom/ns#" term="AppKit" /><title>Revisiting an old post: Streaming and playing an MP3 stream</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Given the attention it received and the number of bugs I know it contained, I wanted to revisit an old post of mine: Streaming and playing an MP3 stream. In this post, I'll talk about the problems the original contained, how I fixed those problems and I'll present the updated result.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Introduction&lt;/h4&gt;
&lt;p&gt;Last September, I wrote a post titled "&lt;a href="http://cocoawithlove.com/2008/09/streaming-and-playing-live-mp3-stream.html"&gt;Streaming and playing an MP3 stream&lt;/a&gt;". The post was largely an experiment &amp;mdash; I just wanted to see if I could play a streaming MP3 by quickly adapting Apple's AudioFileStreamExample to accept an HTTP data stream.&lt;/p&gt;

&lt;p&gt;Unexpectedly, the post became one of my most popular. The attention quickly revealed the limitations in my approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The blend of Objective-C and C was muddled and led to a situation where neither were being used cleanly.&lt;/li&gt;
&lt;li&gt;The boolean flags I copied from the original example were a bad way to describe the playback state and lots of situations were not covered by these flags.&lt;/li&gt;
&lt;li&gt;Sending notifications to the user-interface on a thread that isn't the main thread causes problems.&lt;/li&gt;
&lt;li&gt;The extra thread I added (the download thread) was never thread-safe.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've finally decided to take the time to present a solution to these issues and present an approach which is a little more robust and a little easier to extend if needed.&lt;/p&gt;

&lt;blockquote&gt;You can download the complete &lt;a href="http://github.com/mattgallagher/AudioStreamer/zipball/master"&gt;AudioStreamer project as a zip file&lt;/a&gt; (around 110kB) which contains Xcode projects for both iPhone and Mac OS. You can also &lt;a href="http://github.com/mattgallagher/AudioStreamer"&gt;browse the source code repository&lt;/a&gt;.&lt;/blockquote&gt;

&lt;h4&gt;Limited scope&lt;/h4&gt;

&lt;p&gt;One point should be clarified before I continue: this class is intended for &lt;em&gt;streaming&lt;/em&gt; audio. By streaming, I don't simply mean "an audio file transferred over HTTP". Instead, I mean a continuous HTTP source without an end that continues indefinitely (like a radio station, not a single song).&lt;/p&gt;

&lt;p&gt;Yes, this class will handle fixed-length files transferred over HTTP but it is not ideal for the task.&lt;/p&gt;

&lt;p&gt;This class does not handle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buffering of data to a file&lt;/li&gt;
&lt;li&gt;Seeking within downloaded data&lt;/li&gt;
&lt;li&gt;Feedback about the total length of the file&lt;/li&gt;
&lt;li&gt;Parsing of ID3 metadata&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These things often can't be done on streaming data, so this class doesn't try. See the "Adding other functionality" section for hints about how the class could be reorganised to handle some of these features.&lt;/p&gt;

&lt;h4&gt;Taking code out of C functions&lt;/h4&gt;

&lt;p&gt;Since I had borrowed the &lt;code&gt;AudioFileStream&lt;/code&gt; and &lt;code&gt;AudioQueue&lt;/code&gt; callback functions from Apple's example, they were Standard C.&lt;/p&gt;

&lt;p&gt;My first change was to make these 6 callback functions (7 including the &lt;code&gt;CFReadStream&lt;/code&gt; callback) little more than wrappers around Objective-C methods:&lt;/p&gt;

&lt;pre&gt;void MyPacketsProc(
    void *inClientData,
    UInt32 inNumberBytes,
    UInt32 inNumberPackets,
    const void *inInputData,
    AudioStreamPacketDescription *inPacketDescriptions)
{
    // this is called by audio file stream when it finds packets of audio
    AudioStreamer* streamer = (AudioStreamer *)inClientData;
    [streamer
        handleAudioPackets:inInputData
        numberBytes:inNumberBytes
        numberPackets:inNumberPackets
        packetDescriptions:inPacketDescriptions];
}&lt;/pre&gt;

&lt;p&gt;At a compiled code level, this is a step backwards: all I've done is slowed the program down by an extra Objective-C message send.&lt;/p&gt;

&lt;p&gt;Technically, a C function that takes a "context" pointer (like the &lt;code&gt;inClientData&lt;/code&gt; pointer here) is not significantly different to a method. What a method does is makes data hiding and data abstracted actions easier. Within a method, you can easily access the instance variables of an object and you don't need to explicitly pass context into each function.&lt;/p&gt;

&lt;p&gt;This is the cliché argument in favor of object-orientation &amp;mdash; but it isn't why I reorganized these functions and methods.&lt;/p&gt;

&lt;p&gt;The honest reason why I did it is aesthetics: it is easier to read a class that is implemented using Objective-C methods alone &amp;mdash; it's more consistent. I chose to move towards an Objective-C aesthetic and away from the Standard C aesthetic of the CoreAudio sample code to promote consistent formatting, consistent means of accessing state variables, consistent ways of invoking methods and consistent ways of synchronizing access to the class.&lt;/p&gt;

&lt;h4&gt;Describing state&lt;/h4&gt;

&lt;p&gt;With the majority of code now inside the class, I was in a better position to start handling changes through methods rather than direct member access.&lt;/p&gt;

&lt;p&gt;My original approach to state came from Apple's original example. This example had just one piece of state: a &lt;code&gt;bool&lt;/code&gt; named &lt;code&gt;finished&lt;/code&gt; (which indicated that the run loop should exit).&lt;/p&gt;

&lt;p&gt;The problem with this flag is how simple it is. It is unable to distinguish between the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;End of file, normal automatic stop.&lt;/li&gt;
&lt;li&gt;The user has asked the &lt;code&gt;AudioStreamer&lt;/code&gt; to stop but the &lt;code&gt;AudioQueue&lt;/code&gt; thread has not yet responded.&lt;/li&gt;
&lt;li&gt;An error has occurred before the &lt;code&gt;AudioQueue&lt;/code&gt; thread is created and we must exit.&lt;/li&gt;
&lt;li&gt;We are stopping the &lt;code&gt;AudioQueue&lt;/code&gt; for temporary reasons (clearing it, changing device, seeking to a new point) but we don't want the loop to stop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For Apple's example, there was no problem: the first case was the only one that ever occurred.&lt;/p&gt;

&lt;p&gt;As a hasty solution, I had added &lt;code&gt;started&lt;/code&gt; and &lt;code&gt;failed&lt;/code&gt; flags but these really only covered the first and third case adequately.&lt;/p&gt;

&lt;p&gt;In the end, I realized that the &lt;code&gt;AudioStreamer&lt;/code&gt; needed much more descriptive state where every combination of progress within each thread had a different position:&lt;/p&gt;

&lt;pre&gt;typedef enum
{
    AS_INITIALIZED = 0,
    AS_STARTING_FILE_THREAD,
    AS_WAITING_FOR_DATA,
    AS_WAITING_FOR_QUEUE_TO_START,
    AS_PLAYING,
    AS_BUFFERING,
    AS_STOPPING,
    AS_STOPPED,
    AS_PAUSED
} AudioStreamerState;&lt;/pre&gt;

&lt;p&gt;and when stopping, one of the following values would also be needed:&lt;/p&gt;

&lt;pre&gt;typedef enum
{
    AS_NO_STOP = 0,
    AS_STOPPING_EOF,
    AS_STOPPING_USER_ACTION,
    AS_STOPPING_ERROR,
    AS_STOPPING_TEMPORARILY
} AudioStreamerStopReason;&lt;/pre&gt;

&lt;p&gt;In this way, the state always describes where every thread is and the stop reason explains why a transition is occurring.&lt;/p&gt;

&lt;p&gt;Combining this with an error code that replaces the old &lt;code&gt;failed&lt;/code&gt; flag, I now have a complete desription of the state.&lt;/p&gt;

&lt;p&gt;By cleaning up the state of the object, I was able to make the object capable of state transitions that weren't previously possible including pausing/unpausing and returning to the &lt;code&gt;AS_INITIALIZED&lt;/code&gt; state after a stop (instead of requiring that the class be released after stopping).&lt;/p&gt;

&lt;h4&gt;Notifications&lt;/h4&gt;

&lt;p&gt;In the old version of the project the only way for the user-interface to follow the playback state was to observe the &lt;code&gt;isPlaying&lt;/code&gt; property on the object which reflected the &lt;code&gt;kAudioQueueProperty_IsRunning&lt;/code&gt; property of the AudioQueue.&lt;/p&gt;

&lt;p&gt;This observing was handled through KeyValueObserving. I'm a big fan of KeyValueObserving for its simplicity and ubiquity but this was not the correct place to use it.&lt;/p&gt;

&lt;p&gt;KeyValueObserving always invokes the observer methods in the same thread as the change. Since all changes in AudioStreamer happen in secondary threads, this means that the observer methods were getting invoked in secondary threads.&lt;/p&gt;

&lt;p&gt;Why is this bad? A minor drawback is simply the unexpectedness for the observer but the biggest reason was that the sole purpose of observing this property was to update the user-interface and the user-interface on the iPhone cannot be updated from any thread except the main thread. Even on the Mac, performing updates off the main thread can have unexpected and glitchy results.&lt;/p&gt;

&lt;p&gt;The solution is to retain the &lt;code&gt;NSNotificationCenter&lt;/code&gt; of the thread that first calls &lt;code&gt;start&lt;/code&gt; on the object and use this center to send messages as follows:&lt;/p&gt;

&lt;pre&gt;NSNotification *notification =
    [NSNotification
        notificationWithName:ASStatusChangedNotification
        object:self];
[notificationCenter
    performSelector:@selector(postNotification:)
    onThread:[NSThread mainThread]
    withObject:notification
    waitUntilDone:NO];&lt;/pre&gt;

&lt;p&gt;Don't invoke &lt;code&gt;postNotification:&lt;/code&gt; directly from the secondary thread as, like most methods, it is not thread safe and it could be in use from the main thread.&lt;/p&gt;

&lt;h4&gt;Thread safety&lt;/h4&gt;

&lt;p&gt;Despite adding an extra thread on top of Apple's AudioFileStreamExample, I never really spent any time thinking about thread safety &amp;mdash; a reckless approach to stability. In my defence Apple's example wasn't exactly cautious with its threads and would quit while the &lt;code&gt;AudioQueue&lt;/code&gt;'s thread was still playing the last buffer.&lt;/p&gt;

&lt;p&gt;The most efficient approach to threading is to carefully enter &lt;code&gt;@synchronized&lt;/code&gt; (or &lt;code&gt;NSLock&lt;/code&gt; or &lt;code&gt;pthread_mutex_lock&lt;/code&gt;) in a tight region around any use of a shared variable.&lt;/p&gt;

&lt;p&gt;Unfortunately for the &lt;code&gt;AudioStreamer&lt;/code&gt; class, almost everything in the class is shared. Instead, I decided to go for the decidedly less efficient approach of running almost everything in the class within a &lt;code&gt;@synchronized&lt;/code&gt; section, emerging only at points when control must be yielded to other threads.&lt;/p&gt;

&lt;p&gt;The drawback is that the code rarely runs simultaneously on multiple threads (although threading here is for blocking and I/O, not for multi-threaded performance reasons so that's not a probem). The advantage with this heavy-handed locking approach is that the only threading condition that may cause problems are deadlocks.&lt;/p&gt;

&lt;p&gt;When do deadlocks occurs? Only when you're waiting for another thread to do something while you're inside the synchronized section needed by that other thread. The simple solution: never wait for another thread inside a synchronized section.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AudioStreamer&lt;/code&gt; has three situations where 1 thread waits for another:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The run loop (the &lt;code&gt;AudioFileStream&lt;/code&gt; thread waits for any kind of control communication from the main thread or playback finished notification from the &lt;code&gt;AudioQueue&lt;/code&gt; thread).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;enqueueBuffer&lt;/code&gt; method (&lt;code&gt;AudioFileStream&lt;/code&gt; thread waits for the &lt;code&gt;AudioQueue&lt;/code&gt; thread to free up a buffer).&lt;/li&gt;
&lt;li&gt;Synchronous &lt;code&gt;AudioQueueStop&lt;/code&gt; invocations (waits for the &lt;code&gt;AudioQueue&lt;/code&gt; to release all buffers).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first two points are easy: perform these actions (any any method invocation which invokes them) outside of the &lt;code&gt;@synchronized&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;The final point is harder: the synchronous stop must be performed inside the &lt;code&gt;@synchronized&lt;/code&gt; section to prevent multiple &lt;code&gt;AudioQueueStop&lt;/code&gt; actions occurring at once. To address this, the release of buffers by the &lt;code&gt;AudioQueue&lt;/code&gt; (in &lt;code&gt;handleBufferCompleteForQueue:buffer:&lt;/code&gt;) must perform its work without entering the &lt;code&gt;@synchronized&lt;/code&gt; section (although it's allowed to use the &lt;code&gt;queueBuffersMutex&lt;/code&gt; as normal since that isn't used by anything else during a synchronous stop).&lt;/p&gt;

&lt;p&gt;Of course, every time the &lt;code&gt;@sychronized&lt;/code&gt; section is re-entered, a check must be performed to see if "control communication" has occurred (the class checks this by invoking the &lt;code&gt;isFinishing&lt;/code&gt; method and exiting if it returns &lt;code&gt;YES&lt;/code&gt;).&lt;/p&gt;

&lt;h4&gt;Adding other functionality&lt;/h4&gt;

&lt;h5&gt;Get metadata&lt;/h5&gt;

&lt;p&gt;The easiest source of metadata comes from the HTTP headers. Inside the &lt;code&gt;handleReadFromStream:eventType:&lt;/code&gt; method, use &lt;code&gt;CFReadStreamCopyProperty&lt;/code&gt; to copy the &lt;code&gt;kCFStreamPropertyHTTPResponseHeader&lt;/code&gt; property from the &lt;code&gt;CFReadStreamRef&lt;/code&gt;, then you can use &lt;code&gt;CFHTTPMessageCopyAllHeaderFields&lt;/code&gt; to copy the header fields out of the response. For many streaming audio servers, the stream name is one of these fields.&lt;/p&gt;

&lt;p&gt;The considerably harder source of metadata are the ID3 tags. ID3v1 is always at the end of the file (so is useless when streaming). ID3v2 is located at the start so may be more accessible.&lt;/p&gt;

&lt;p&gt;I've never read the ID3 tags but I suspect that if you cache the first few hundred kilobytes of the file somewhere as it loads, open that cache with &lt;code&gt;AudioFileOpenWithCallbacks&lt;/code&gt; and then read the &lt;code&gt;kAudioFilePropertyID3Tag&lt;/code&gt; with &lt;code&gt;AudioFileGetProperty&lt;/code&gt; you may be able to read the ID3 data (if it exists). Like I said though: I've never actually done this so I don't know for certain that it would work.&lt;/p&gt;

&lt;h5&gt;Stream fixed-length files&lt;/h5&gt;

&lt;p&gt;The biggest variation you may want to make to the class is to download fixed-length files, rather than streaming audio.&lt;/p&gt;

&lt;p&gt;To handle this, the best approach is to remove the download from the class entirely. Download elsewhere and when "enough" (an amount you should determine on your own) of the file is downloaded, start a variation of the class that plays by streaming from a file on disk.&lt;/p&gt;

&lt;p&gt;To adapt the class for streaming from a file on disk, remove the &lt;code&gt;CFHTTPMessageRef&lt;/code&gt; and &lt;code&gt;CFReadStreamRef&lt;/code&gt; code from &lt;code&gt;openFileStream&lt;/code&gt; and replace it with &lt;code&gt;NSFileHandle&lt;/code&gt; code that uses &lt;code&gt;waitForDataInBackgroundAndNotify&lt;/code&gt; to asynchronously stream the file in the same way that &lt;code&gt;CFReadStreamRef&lt;/code&gt; streamed the network data.&lt;/p&gt;

&lt;p&gt;Once you're streaming from a file, you'll probably want to permit seeking within the file. I've already put hooks within the file to seek (set the &lt;code&gt;seekNeeded&lt;/code&gt; flag to true and set the &lt;code&gt;seekTime&lt;/code&gt; to the time in seconds to which you want to seek) &amp;mdash; however, the mechanics of seeking within the file would be dependent on how you access the file.&lt;/p&gt;

&lt;p&gt;Incidentally, the &lt;code&gt;AudioFileStreamSeek&lt;/code&gt; function seems completely broken. If you can't get it to work (as I couldn't) just seek to a new point in the file, set &lt;code&gt;discontinuous&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; and let &lt;code&gt;AudioFileStream&lt;/code&gt; deal with it.&lt;/p&gt;

&lt;h5&gt;Handling data interruptions&lt;/h5&gt;

&lt;p&gt;At the moment, if the &lt;code&gt;AudioQueue&lt;/code&gt; has no more buffers to play, the state will transition to &lt;code&gt;AS_BUFFERING&lt;/code&gt;. At this point, no specific action is taken to resolve this situation &amp;mdash; it assumes that the network will eventually resume and requeue enough buffers.&lt;/p&gt;

&lt;p&gt;I actually expect there will be cases where this action is insufficient &amp;mdash; you may need to ensure that the &lt;code&gt;AudioQueue&lt;/code&gt; is paused until enough buffers are filled before resuming or even restart the download entirely. I haven't experimented much since it is easiest with streaming audio just to stop and start new.&lt;/p&gt;

&lt;p&gt;Incidentally, if you're curious to know how many audio buffers are in use at any given time, uncomment the &lt;code&gt;NSLog&lt;/code&gt; line in the &lt;code&gt;handleBufferCompleteForQueue:buffer:&lt;/code&gt; method. This will log how many 1 kilobyte audio buffers are queued waiting for playback (when the queue reaches zero, the &lt;code&gt;AudioStreamer&lt;/code&gt; enters the &lt;code&gt;AS_BUFFERING&lt;/code&gt; state).&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the complete &lt;a href="http://github.com/mattgallagher/AudioStreamer/zipball/master"&gt;AudioStreamer project as a zip file&lt;/a&gt; (around 110kB) which contains Xcode projects for both iPhone and Mac OS. You can also &lt;a href="http://github.com/mattgallagher/AudioStreamer"&gt;browse the source code repository&lt;/a&gt;.&lt;/blockquote&gt;

&lt;p&gt;The functionality of this new version has not changed greatly &amp;mdash; my purposed was to present a version that is more stable and tolerant of unexpected situations, rather than add new features.&lt;/p&gt;

&lt;p&gt;As before, the AudioStreamer class should work on Mac OS X 10.5 and on the iPhone (SDK 2.0 and greater).&lt;/p&gt;

&lt;p&gt;The source repository is hosted on github so you can browse, fork or track updates as you choose. I will likely update again in future (I can't imagine I've written this much code without causing more problems) and this way, you can see the changes I've made.&lt;/p&gt;

&lt;p&gt;I hope this post has shown you a number of problems that can happen when code is written hastily. This doesn't mean you should always avoid hastily written code (timeliness and proof of concepts are important) but it does mean you should be practised at refactoring code and not simply slap poor fixes onto code that doesn't cleanly solve a problem in the first place.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1227978711636506887?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1227978711636506887?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1227978711636506887?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/06/revisiting-old-post-streaming-and.html" title="Revisiting an old post: Streaming and playing an MP3 stream" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author></entry><entry gd:etag="W/&quot;DEYAQnY6fip7ImA9WxJXFko.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1967112249403196365</id><published>2009-06-10T03:32:00.001-07:00</published><updated>2009-06-10T16:22:23.816-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-10T16:22:23.816-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Objective-C" /><category scheme="http://www.blogger.com/atom/ns#" term="object-oriented design" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Standard C" /><title>Method names in Objective-C</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Compared to other languages, method names in Objective-C are weird. They're long, they're wordy, they include names for the parameters and they seem to repeat information you can get elsewhere. Despite these apparent negatives, Objective-C method naming can save you time and effort. I'll show you how methods are named so that you can predict them without documentation and understand how methods work and how they use their parameters from their names alone.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;

&lt;h4&gt;Introduction: Objective-C is an ugly duckling&lt;/h4&gt;

&lt;p&gt;Along with square-brackets and its largely Apple-exclusive nature, method names are one of the most commonly decried parts of Objective-C. I've seen them criticized for being:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Long and wordy&lt;/li&gt;
&lt;li&gt;Repetitious or redundant&lt;/li&gt;
&lt;li&gt;Filled with names for each parameter&lt;/li&gt;
&lt;li&gt;Camel-case&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;While every one of these points is true, none of them is really a negative &amp;mdash; although camel-case is a subjective, aesthetic point and I'll ignore it since I'll only consider the &lt;em&gt;structural&lt;/em&gt; aspects of method naming conventions in this post.&lt;/p&gt;

&lt;p&gt;Objective-C methods names are some of the most predictable, regular, self-descriptive methods in any C-derivative language &amp;mdash; and it is these points that allow it to be so. Of course, these benefits are lost unless you know the conventions well enough to understand and predict them.&lt;/p&gt;

&lt;h4&gt;Background: naming conventions in other C-like languages&lt;/h4&gt;

&lt;p&gt;To help you understand the reasoning behind Objective-C's method names, I'll start by describing how methods and functions are named in C. I'm starting with C because Objective-C's method naming is, in some respects, an extension of C's naming style, adapted to overcome the limitations.&lt;/p&gt;

&lt;h5&gt;Standard C's naming style&lt;/h5&gt;

&lt;p&gt;Yes, Standard C does have some implicit naming conventions. Many standard C functions are composed of three parts:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;An indication of the data type acted upon&lt;/li&gt;
&lt;li&gt;The action&lt;/li&gt;
&lt;li&gt;A description of the secondary object&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;We can see examples of these in these functions:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;&lt;strong&gt;sscanf&lt;/strong&gt;&lt;/code&gt; - "s" (acts upon a &lt;code&gt;char *&lt;/code&gt;), "scan" (extract character data from the string), "f" (format string is the secondary object)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;strong&gt;fprintf&lt;/strong&gt;&lt;/code&gt; - "f" (acts upon a &lt;code&gt;FILE&lt;/code&gt;), "print" (outputs character data to the file), "f" (format string is the secondary object)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;strong&gt;strlen&lt;/strong&gt;&lt;/code&gt; - "str" (acts upon a &lt;code&gt;char *&lt;/code&gt;), "len" (compute the length). No secondary object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;strong&gt;fesetround&lt;/strong&gt;&lt;/code&gt; - "fe" (acts upon the "floating point environment"), "set" (changes a state value), "round" (a new rounding value is the secondary object).&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Standard C's naming style fails&lt;/h5&gt;

&lt;p&gt;For these methods, this style works well. The problem is that components are so short (often single letters) that it is difficult to know for certain to what they refer. Many of the methods in math.h show these limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&lt;strong&gt;lround&lt;/strong&gt;&lt;/code&gt; - "l" (no longer an "acts upon", this first part now indicates "returns a &lt;code&gt;long&lt;/code&gt;"), "round" (round to the nearest integer). No description of the primary parameter &amp;mdash; you are expected to assume a &lt;code&gt;double&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&lt;strong&gt;acosl&lt;/strong&gt;&lt;/code&gt; - The "l" in this case is the primary parameter and means &lt;code&gt;long double&lt;/code&gt; whereas it meant &lt;code&gt;long&lt;/code&gt; in the &lt;code&gt;lround&lt;/code&gt; method above. The "a" here is not a prefix, it is part of the action component.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;This is where naming styles in C break down &amp;mdash; while math.h does have naming conventions, they are all its own. You can learn the tricks of math.h but they are unique to that library, not a standard that applies to all functions.&lt;/p&gt;

&lt;p&gt;Beyond these issues C, suffers from a broader lack of adherence to &lt;em&gt;any&lt;/em&gt; convention, let alone a consistent one. Most functions are really just a 4 to 6 character description of the action performed. While this may be all that is required at a technical level, it makes it almost impossible to know how to use functions like &lt;code&gt;system&lt;/code&gt;, &lt;code&gt;raise&lt;/code&gt;, &lt;code&gt;atexit&lt;/code&gt; or even &lt;code&gt;malloc&lt;/code&gt; for the first time without reading the documentation.&lt;/p&gt;

&lt;h5&gt;Other languages&lt;/h5&gt;

&lt;p&gt;Few other languages have a distinct approach to method structure. The overriding convention in the main languages I use (C++, C#, Java) is simply a short verb plus possible modifier.&lt;/p&gt;

&lt;p&gt;Some languages do have their own aesthetics (for example, the C++ Standard Library uses terse underscore delimited words) but this doesn't represent a structural convention.&lt;/p&gt;

&lt;p&gt;The reason why these languages have abandoned the three part style of Standard C functions is that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The data type acted upon is now the object upon which the method is invoked, removing the need to explain this part.&lt;/li&gt;
&lt;li&gt;Parameter overloading means that a description of any parameter needs to be vague (since the parameter itself may be used inconsistently).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So methods end up being little more than a verb plus an optional modifier term.&lt;/p&gt;

&lt;p&gt;The result is that methods with subtle actions or that use their parameters in specific ways can only be used by thoroughly examining the documentation.&lt;/p&gt;

&lt;h4&gt;Method naming conventions in Objective-C&lt;/h4&gt;

&lt;p&gt;Objective-C aims to be substantially more self-documenting than its peers. The intent is that all methods in all classes should be able to follow the same set of rules so that subtleties of behavior are easy to see and understand &amp;mdash; even when you are new to the class.&lt;/p&gt;

&lt;p&gt;This aim combines with the named parameters in Objective-C to produce methods which are quite distinct compared to other languages.&lt;/p&gt;

&lt;p&gt;Given the lack of convention in other languages and the unusual nature of Objective-C's named parameters, it's no so surprising that method names in Objective-C are confronting to new Objective-C programmers.&lt;/p&gt;

&lt;h5&gt;Structure of an Objective-C method name&lt;/h5&gt;

&lt;p&gt;Objective-C methods are composed of a few different components. I'll list the components here, examples follow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If there is a return value, the method should begin with the property name of the return value (for accessor methods), or the class of the return value (for factory methods).&lt;/li&gt;
&lt;li&gt;A verb describing either an action that changes the state of the receiver or a secondary action the receiver may take. Methods that don't result in a change of state to the receiver often omit this part.&lt;/li&gt;
&lt;li&gt;A noun if the first verb acts on a direct object (for example a property of the receiver) and that property is not explicit in the name of the first parameter.&lt;/li&gt;
&lt;li&gt;If the primary parameter is an indirect object to the main verb of the method, then a preposition (i.e. "by", "with", "from") is used. This preposition partly serves to indicate the manner in which the parameter is used but mostly serves to make the sentence more legible.&lt;/li&gt;
&lt;li&gt;If a preposition was used and the first verb doesn't apply to the primary parameter or isn't present then another verb describing direct action involving the primary parameter may be used.&lt;/li&gt;
&lt;li&gt;A noun description (often a class or class-like noun) of the primary parameter, if this is not explicit in one of the verbs.&lt;/li&gt;
&lt;li&gt;Subsequent parameter names are noun descriptions of those parameters. Prepositions, conjunctions or secondary verbs may precede the name of a subsequent parameter but only where the subsequent parameter is of critical importance to the method. These extra terms are a way to highlight importance of secondary parameters. In some rarer cases secondary parameter names may be a preposition without a noun to indicate a source or destination.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In addition, an Objective-C method should be maximally readable &amp;mdash; its reading should flow like a sentence and abbreviations should be avoided except where they are universally known (and even then, abbreviations to syllables rather than single letters are preferred).&lt;/p&gt;

&lt;p&gt;That's a lot to consider. Fortunately, most components are only relevant to specific kinds of method.&lt;/p&gt;

&lt;h5&gt;Applying the naming convention to property accessors&lt;/h5&gt;

&lt;pre&gt;length&lt;/pre&gt;

&lt;p&gt;This method is shows the typical form of a getter method for a property or calculated value. Only the first component of the method name applies.&lt;/p&gt;

&lt;p&gt;The biggest point to note with respect to other languages is that getter methods don't use the verb "get" because no explicit action or state change is required to extract this property (implicit actions or actions taken for internal reasons should not be communicated through the method name).&lt;/p&gt;

&lt;pre&gt;encodedLength&lt;/pre&gt;

&lt;p&gt;This method shows a variant length method where a modifier is used to describe the length. We put the modifier before the property name because a structure like &lt;code&gt;lengthWhenEncoded&lt;/code&gt; gets too close to &lt;code&gt;lengthForEncoding:&lt;/code&gt; which would be used if the encoding was passed in as a parameter.&lt;/p&gt;

&lt;pre&gt;sharedApplication&lt;/pre&gt;

&lt;p&gt;Singleton accessors (like this accessor for the global &lt;code&gt;UIApplication&lt;/code&gt; object) and other global data accessors take exactly the form as instance accessors. A description of the return value ("Application" in this case) plus an adjective to disambiguate it (in this case, disambiguation is required because a class name on its own is expected to be a factory method &amp;mdash; see below). The term "shared" is used by convention to identify singletons.&lt;/p&gt;

&lt;pre&gt;doubleValue&lt;/pre&gt;

&lt;p&gt;This method has the same structure as the previous method but shows how the returned class is sometimes the modifier when used in conjunction with an abstract property like "value".&lt;/p&gt;

&lt;pre&gt;isEditable&lt;/pre&gt;

&lt;p&gt;This method is actually an exception to the conventional rules. The verb "is" shouldn't be there &amp;mdash; verbs are normally reserved for describing state change or secondary action.&lt;/p&gt;

&lt;p&gt;I guess that this style for accessors that return a &lt;code&gt;BOOL&lt;/code&gt; developed to make the method read more like a sentence. You could also argue that "is" is a passive verb so it isn't indicating an action.&lt;/p&gt;

&lt;pre&gt;setLength:&lt;/pre&gt;

&lt;p&gt;The setter method is not composed in the same way as the getter. With no return value, the first part is a verb describing the action: "set".&lt;/p&gt;

&lt;p&gt;The second part, "Length" may be considered to the direct object of the verb component (i.e. the internal property). In this case, it is also the name of the first parameter. Since they communicate the same information, only one is used.&lt;/p&gt;

&lt;p&gt;Setter methods with prepositions before the first parameter like &lt;code&gt;setValueUsingDouble:&lt;/code&gt; and &lt;code&gt;setValueUsingNumber:&lt;/code&gt; are rarely used, even though they may seem like a good way to unambiguously set a property like "value" using different data types. Instead, the property itself is normally give a different name (i.e. &lt;code&gt;setDoubleValue:&lt;/code&gt; or &lt;code&gt;setNumberValue:&lt;/code&gt;). In this way, there is only ever one setter for a given property (although properties may contain dependencies).&lt;/p&gt;

&lt;h5&gt;Applying the naming convention to factory methods&lt;/h5&gt;

&lt;pre&gt;string&lt;/pre&gt;

&lt;p&gt;This &lt;code&gt;NSString&lt;/code&gt; method returns an empty string. It takes exactly the same format as a getter method, except that you invoke it on a class object, not an instance and it doesn't include a property name.&lt;/p&gt;

&lt;p&gt;It may seem like this method is providing redundant information &amp;mdash; we already know that a factory method for a class will return an instance of the same class &amp;mdash; but identifying the return type here has two purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;factory method are identified precisely because they start with the class' name&lt;/li&gt;
&lt;li&gt;it maintains consistency (always describe the return value when it is the purpose of the method)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A quick follow up to that second point though: the return value only needs to be described when it is the purpose of the method. &lt;code&gt;BOOL&lt;/code&gt; values returned as an error indicator and other cases where the return value is a secondary effect (like &lt;code&gt;autorelease&lt;/code&gt; which returns the receiver) do not need to describe the return value.&lt;/p&gt;

&lt;pre&gt;stringWithString:&lt;/pre&gt;

&lt;p&gt;The parameter here is named "String", indicating that it is an instance of &lt;code&gt;NSString&lt;/code&gt; with no other constraints. The correct way to read this method is that it creates a new string in the simplest way possible from its string parameter &amp;mdash; i.e. a copy of the string.&lt;/p&gt;

&lt;p&gt;The preposition here is of little semantic purpose except to make the method name read like a sentence. The choice of preposition is simply: whatever is most appropriate if you read it like a sentence. For this reason class factory methods normally use "With" but instance factory methods normally use "By" because it implies some involvement of the receivers data (like &lt;code&gt;stringByAppendingString:&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;NSArray&lt;/code&gt; method &lt;code&gt;isEqualToArray&lt;/code&gt; shows a state interrogation with a preposition but again, the preposition is chosen simply to make the method name read like a sentence.&lt;/p&gt;

&lt;h5&gt;Applying the naming convention to action methods&lt;/h5&gt;

&lt;pre&gt;release&lt;/pre&gt;

&lt;p&gt;This is an example of a simple action method: a verb describing how the method changes state or performs secondary actions.&lt;/p&gt;

&lt;pre&gt;addObject:&lt;/pre&gt;

&lt;p&gt;Again, a very simple method: verb plus a noun describing the first parameter (any "Object").&lt;/p&gt;

&lt;pre&gt;addObserver:forKeyPath:options:context:&lt;/pre&gt;

&lt;p&gt;The important addition to see here is the use of the preposition "for" in front of the second parameter. Yes, "KeyPath" is the indirect object of the method's verb "add" but the real purpose here is to highlight the importance of this parameter &amp;mdash; pointing out that this parameter is more important than parameters which follow.&lt;/p&gt;

&lt;p&gt;To explain this, consider that the method is not &lt;code&gt;addObject:forKeyPath:usingOptions:andContext:&lt;/code&gt; &amp;mdash; the options and context are really peripheral parameters whereas keyPath is an important consideration, despite being the second parameter.&lt;/p&gt;

&lt;p&gt;This method can be compared to the very similar &lt;code&gt;NSNotificationCenter&lt;/code&gt; method &lt;code&gt;addObserver:selector:name:object:&lt;/code&gt;. In the case of the &lt;code&gt;NSNotificationCenter&lt;/code&gt; method, &lt;code&gt;name:&lt;/code&gt; is the corresponding parameter to &lt;code&gt;forKeyPath:&lt;/code&gt; and yet no preposition is used (it is not &lt;code&gt;forName:&lt;/code&gt;). This reflects the fact that the name parameter is optional (can be &lt;code&gt;nil&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;However you should not infer that lack of preposition means "optional" &amp;mdash; far from it. Instead, the correct meaning is preposition means more important than other secondary parameters. The &lt;code&gt;selector:&lt;/code&gt; parameter of the &lt;code&gt;addObserver:selector:name:object:&lt;/code&gt; method is mandatory but is given no special status in the method. It is necessary for routing the notification but much of the time will simply reflect the notifications it observes (i.e. &lt;code&gt;@selector(windowWillCloseNotification:)&lt;/code&gt;).&lt;/p&gt;

&lt;h5&gt;A small exception: delegate methods&lt;/h5&gt;

&lt;pre&gt;windowDidChangeScreen:&lt;/pre&gt;

&lt;p&gt;This method begins with the name of a class but it is not a factory method nor a method which returns a mutated version of the receiver. It is actually a delegate method and delegate methods don't really follow any of the conventions.&lt;/p&gt;

&lt;p&gt;If it were following the conventional standard its name would be &lt;code&gt;receiveWindowDidChangeScreenNotification:&lt;/code&gt;. You could argue that delegate methods are passive &amp;mdash; the delegate isn't being asked to perform an action, it is being told that something else performed an action &amp;mdash; so omitting a verb is permissible. For my part, the break with convention makes me sad inside.&lt;/p&gt;

&lt;p&gt;Further confusing things, the first parameter of the delegate method is rarely identified by the closest noun. Instead the first parameter is either the object sending the notification or it is a notification object (which will contain the sender). In the example above, the closest noun is "screen" but the first parameter is an &lt;code&gt;NSNotification&lt;/code&gt;. In the case of &lt;code&gt;applicationOpenUntitledFile:&lt;/code&gt; the closest noun is "File" but the parameter is the &lt;code&gt;NSApplication&lt;/code&gt; object that sent the message.&lt;/p&gt;

&lt;h4&gt;Summary&lt;/h4&gt;

&lt;p&gt;In describing method formats, I've repeated myself quite a few times. The reality is that Objective-C uses one method naming convention almost everywhere.&lt;/p&gt;

&lt;p&gt;Objective-C method names are very regular. So regular that you should be able to predict the names for methods without checking the documentation &amp;mdash; start typing the method name as you guess it, then autocomplete. More than simply predicting the name, you can normally predict how parameters are used, so again you avoid documentation and know what you need.&lt;/p&gt;

&lt;p&gt;Looking at the criticisms levelled at Objective-C method names that I listed at the start:&lt;/p&gt;

&lt;h5&gt;Long and wordy&lt;/h5&gt;

&lt;p&gt;Yes, Objective-C methods are made to read like sentences. They contain prepositions (something almost never seen in other languages), they contain type of the return parameter, they use full words instead of abbreviations.&lt;/p&gt;

&lt;p&gt;The purpose is to make the method as quick to read as possible.&lt;/p&gt;

&lt;p&gt;This is a good trade to make since you will read a method many times but only type it once (with code completion, less than once).&lt;/p&gt;

&lt;blockquote&gt;Xcode will suggest code completion automatically. Hit return at any time to pick the completion it offers. Hit the Code Sense Completion key (F5 by default) and it will present a popup list of matching options. Control-/ will step through the parameters so you can fill them in.&lt;/blockquote&gt;

&lt;h5&gt;Repetitious or redundant&lt;/h5&gt;

&lt;p&gt;While methods like &lt;code&gt;+[UIApplication sharedApplication]&lt;/code&gt; may seem redundant, the reality is that &lt;code&gt;+[UIApplication shared]&lt;/code&gt; would have a different meaning (it would be an accessor for the static class property named "shared") and  &lt;code&gt;+[UIApplication singleton]&lt;/code&gt; by omitting a class name fails to communicate that the method also works as a factory method on the first invocation &amp;mdash; repeating the class name has meaning, it is not redundant.&lt;/p&gt;

&lt;h5&gt;Filled with names for each parameter&lt;/h5&gt;

&lt;p&gt;Yes they are but these names makes it much easier to determine what each parameter is and allows metadata like importance to be conveyed.&lt;/p&gt;

&lt;h5&gt;Camel-case&lt;/h5&gt;

&lt;p&gt;Yes. The choice over underscore delimited words is largely aesthetic. Although the choice over Pascal-case (same as camel-case but where the first letter of the first word is uppercase not lowercase) is because uppercase initial letters are reserved for names with global scope &amp;mdash; like class names, function names and global constants.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;Few other languages have conventions that are as rigourously applied as those in Objective-C. Conventions are annoying to learn &amp;mdash; as they may seem arbitrary and unnecessary at first glance &amp;mdash; but once learned, they are regular and predictable with few surprises. When trying to get the computer to obey, that's good.&lt;/p&gt;

&lt;p&gt;Further reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocLanguageSummary.html#//apple_ref/doc/uid/TP30001163-CH3-TPXREF106"&gt;Naming conventions in the Objective C 2.0 Language Summary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282"&gt;Coding Guidelines for Cocoa: Naming Methods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1967112249403196365?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/1967112249403196365/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=1967112249403196365" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1967112249403196365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1967112249403196365?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/06/method-names-in-objective-c.html" title="Method names in Objective-C" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEAHQHg8fyp7ImA9WxJXFk0.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-3323254146374043462</id><published>2009-06-03T15:35:00.001-07:00</published><updated>2009-06-09T19:58:51.677-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-09T19:58:51.677-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><category scheme="http://www.blogger.com/atom/ns#" term="Standard C" /><title>Base64 encoding options on the Mac and iPhone</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;On Unix platforms, a common approach for Base64 encoding is to use libcrypto (the OpenSSL library). However, like most C libraries, you need to wrap it to integrate with Objective-C data types (like NSData and NSString) and it isn't available on the iPhone. I'll show you how to handle base64 encoding/decoding with OpenSSL and without so you can handle the Mac and iPhone equally.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Introduction&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt; is an encoding for transferring binary data in 7-bit text. Originally used in &lt;a href="http://en.wikipedia.org/wiki/MIME#Content-Transfer-Encoding"&gt;email&lt;/a&gt;, it is also used for binary encoding data in HTML files. Another common use for Base64 is in &lt;a href="http://en.wikipedia.org/wiki/Basic_access_authentication"&gt;HTTP Basic Access Authentication&lt;/a&gt; where it is used to transfer login details (which might not be printable characters).&lt;/p&gt;

&lt;p&gt;The key library for handling Base64 on the Mac is normally libcrypto (the OpenSSL library), so it's a little disappointing that libcrypto isn't available on the iPhone.&lt;/p&gt;

&lt;h4&gt;Using OpenSSL&lt;/h4&gt;

&lt;h5&gt;Via the command line&lt;/h5&gt;

&lt;p&gt;On the Mac, you can handle simple encoding tasks like base64 encoding with OpenSSL on the command line:&lt;/p&gt;

&lt;pre&gt;echo "Base64 encode this text." | openssl enc -base64&lt;/pre&gt;

&lt;p&gt;gives the encoding result:&lt;/p&gt;

&lt;pre&gt;QmFzZTY0IGVuY29kZSB0aGlzIHRleHQuCg==&lt;/pre&gt;

&lt;p&gt;The reverse is handled in the following manner:&lt;/p&gt;

&lt;pre&gt;echo "QmFzZTY0IGVuY29kZSB0aGlzIHRleHQuCg==" | openssl enc -d -base64&lt;/pre&gt;

&lt;p&gt;giving&lt;/p&gt;

&lt;pre&gt;Base64 encode this text.&lt;/pre&gt;

&lt;h5&gt;In code&lt;/h5&gt;

&lt;p&gt;As you'd expect, doing the same work in code takes a little more typing. First, we're using a library, so we need to include it (in your Project's Build Settings under Other Linker Flags add the flag &lt;code&gt;-lcrypto&lt;/code&gt;). Once that's done, you should be able to use the following method in a category on &lt;code&gt;NSData&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;#include &amp;lt;openssl/bio.h&amp;gt;
#include &amp;lt;openssl/evp.h&amp;gt;

- (NSString *)base64EncodedString
{
    // Construct an OpenSSL context
    BIO *context = BIO_new(BIO_s_mem());

    // Tell the context to encode base64
    BIO *command = BIO_new(BIO_f_base64());
    context = BIO_push(command, context);

    // Encode all the data
    BIO_write(context, [self bytes], [self length]);
    BIO_flush(context);

    // Get the data out of the context
    char *outputBuffer;
    long outputLength = BIO_get_mem_data(context, &amp;outputBuffer);
    NSString *encodedString = [NSString
        stringWithCString:outputBuffer
        length:outputLength];

    BIO_free_all(context);

    return encodedString;
}
&lt;/pre&gt;

&lt;p&gt;To handle a Base64 encode.&lt;/p&gt;

&lt;p&gt;By default, &lt;code&gt;encodedString&lt;/code&gt; will have newlines every 64 characters. If needed, you can disable the inclusion of newlines by adding the following line before the &lt;code&gt;BIO_write&lt;/code&gt;:&lt;/p&gt; 

&lt;pre&gt;BIO_set_flags(context, BIO_FLAGS_BASE64_NO_NL);&lt;/pre&gt;

&lt;p&gt;Tthe "BIO" system (I think it stands for buffered I/O) is not very symmetric so the code for decoding is quite different:&lt;/p&gt; 

&lt;pre&gt;+ (NSData *)dataByDase64DecodingString:(NSString *)decode
{
    decode = [decode stringByAppendingString:@"\n"];
    NSData *data = [decode dataUsingEncoding:NSASCIIStringEncoding];
    
    // Construct an OpenSSL context
    BIO *command = BIO_new(BIO_f_base64());
    BIO *context = BIO_new_mem_buf((void *)[data bytes], [data length]);
        
    // Tell the context to encode base64
    context = BIO_push(command, context);

    // Encode all the data
    NSMutableData *outputData = [NSMutableData alloc];
    
    #define BUFFSIZE 256
    int len;
    char inbuf[BUFFSIZE];
    while ((len = BIO_read(context, inbuf, BUFFSIZE)) &gt; 0)
    {
        [outputData appendBytes:inbuf length:len];
    }

    BIO_free_all(context);
    [data self]; // extend GC lifetime of data to here

    return outputData;
}&lt;/pre&gt;

&lt;p&gt;An interesting point to note at the top of this function: I add an extra newline to the start of the string. This is because if you have not disabled newlines and the string does not contain at least 1 newline, &lt;code&gt;BIO_read&lt;/code&gt; will fail.&lt;/p&gt;

&lt;h4&gt;Handling Base64 on the iPhone&lt;/h4&gt;

&lt;p&gt;Using libcrypto isn't possible by default on the iPhone &amp;mdash; the library isn't there. You could probably build libcrypto.a and link it statically against your app but that can be difficult to set up and would require that you notify Apple that your app contains encryption.&lt;/p&gt;

&lt;p&gt;Normally, it is better to avoid libcrypto on the iPhone. The other functions that libcrypto handles can be found elsewhere:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;md5 &amp;mdash; use the CommonCrypto implementation &lt;code&gt;CC_MD5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;sha &amp;mdash; use the CommonCrypto implementation &lt;code&gt;CC_SHA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Public/Private Key Encryption/Decryption &amp;mdash; use the &lt;code&gt;SecKeyEncrypt&lt;/code&gt;/&lt;code&gt;SecKeyDecrypt&lt;/code&gt; functions in the Security framework&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;You can find the documentation for the Security Framework by performing a standard Xcode API lookup. For some reason though, the CommonCrypto functions only appear in a full-text search.&lt;/p&gt;

&lt;p&gt;The Base64 functionality of OpenSSL doesn't have an accessible equivalent on the iPhone, even though &lt;code&gt;NSURLConnection&lt;/code&gt;, &lt;code&gt;CFHTTPMessageRef&lt;/code&gt; and WebKit must all have access to an implementation &amp;mdash; whatever they use is not accessible.&lt;/p&gt;

&lt;h5&gt;Encoding Base64&lt;/h5&gt;

&lt;p&gt;Fortunately, Base64 is a fairly simple encoding. At its heart, it looks like this:&lt;/p&gt;

&lt;pre&gt;static unsigned char base64EncodeLookup[65] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

//
// Inner loop: turn 3 bytes into 4 base64 characters
//
outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] &amp; 0xFC) &amp;gt;&amp;gt; 2];
outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] &amp; 0x03) &amp;lt;&amp;lt; 4)
    | ((inputBuffer[i + 1] &amp; 0xF0) &amp;gt;&amp;gt; 4)];
outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] &amp; 0x0F) &amp;lt;&amp;lt; 2)
    | ((inputBuffer[i + 2] &amp; 0xC0) &amp;gt;&amp;gt; 6)];
outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] &amp; 0x3F];&lt;/pre&gt;

&lt;p&gt;This might be a little ugly to look at if you're not use to seeing bitmasks and bitshifts but it is only a couple lines. It does little more than the comment states: it turns 3 bytes into 4 chars, with the specific chars specified by the &lt;code&gt;base64EncodeLookup&lt;/code&gt; mapping.&lt;/p&gt;

&lt;p&gt;Of course, while this code handles the center of the main loop, there's almost a hundred lines total in the complete implementation that I wrote.&lt;/p&gt;

&lt;p&gt;As part of keeping the function optimal, I wanted to keep the conditionals out of the inner loop (making vectorizing easier). I succeeded and there are no conditionals in the inner loop but this means that there are a few tail conditions to handle in the epilogue.&lt;/p&gt;

&lt;p&gt;I also wanted to calculate the exact size that would be required for the output buffer, so it can be allocated once with no waste, but this too occupies a few lines worth of space.&lt;/p&gt;

&lt;h5&gt;Decoding Base64&lt;/h5&gt;

&lt;p&gt;Decoding works similarly to encoding, except that in decoding we are reducing 4 characters down to 3 bytes instead of vice versa:&lt;/p&gt;

&lt;pre&gt;//
// Store the 6 bits from each of the 4 characters as 3 bytes
//
outputBuffer[j] = (accumulated[0] &amp;lt;&amp;lt; 2) | (accumulated[1] &amp;gt;&amp;gt; 4);
outputBuffer[j + 1] = (accumulated[1] &amp;lt;&amp;lt; 4) | (accumulated[2] &amp;gt;&amp;gt; 2);
outputBuffer[j + 2] = (accumulated[2] &amp;lt;&amp;lt; 6) | accumulated[3];&lt;/pre&gt;

&lt;p&gt;More interesting than the code in this case is the lookup table that each of these accumulated bytes passes through before being used here:&lt;/p&gt;

&lt;pre&gt;//
// Definition for "masked-out" areas of the base64DecodeLookup mapping
//
#define xx 65

//
// Mapping from ASCII character to 6 bit pattern.
//
static unsigned char base64DecodeLookup[256] =
{
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63, 
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx, 
    xx,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx, 
    xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
    xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 
};&lt;/pre&gt;

&lt;p&gt;The "&lt;code&gt;xx&lt;/code&gt;"s in this table are just a &lt;code&gt;#define&lt;/code&gt; of 65 (i.e. outside the valid range of Base64) but they provide an interesting visual representation of the 6-bits that each Base64 character can occupy within the 8-bit byte.&lt;/p&gt;

&lt;p&gt;I was unable to remove all of the conditionals from the inner loop of the decode side and keep the "skip over invalid characters" requirement.&lt;/p&gt;

&lt;p&gt;This "skip over invalid characters" stage (where characters are accumulated until 4 valid characters are found) is handled by the following loop (which immediately preceeds the previous "store the 6 bits from each of the 4 characters as 3 bytes" code):&lt;/p&gt;

&lt;pre&gt;//
// Accumulate 4 valid characters (ignore everything else)
//
unsigned char accumulated[BASE64_UNIT_SIZE];
size_t accumulateIndex = 0;
while (i &lt; length)
{
    unsigned char decode = base64DecodeLookup[inputBuffer[i++]];
    if (decode != xx)
    {
        accumulated[accumulateIndex] = decode;
        accumulateIndex++;
        
        if (accumulateIndex == BASE64_UNIT_SIZE)
        {
            break;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;This is the only part which makes the decode stage sub-optimal. If you had Base64 input data with no newlines and no other characters requiring skipping, I think you could remove this section entirely so that the inner loop of the decode function could be vectorizable.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;Download the &lt;a href="http://cocoawithlove.googlepages.com/NSData_Base64.zip"&gt;NSData+Base64 class and header&lt;/a&gt; (4kB).&lt;/blockquote&gt;

&lt;p&gt;In this post, I've shown you how to use the default command-line and library options for Base64 handling on Mac OS X. I've also shown you the approach I use for Base64 encoding and decoding on the iPhone.&lt;/p&gt;

&lt;p&gt;The libcrypto libraries (when available) are not as tight and simple as custom code for the task but do have the advantage that the pipeline for feeding data into them is more configurable.&lt;/p&gt;

&lt;p&gt;I'm certainly not the only one to present C libraries for Base64 encoding that will work on the iPhone but the approach I've used should be efficient (especially the internal implementations in the C-functions) and it should drop into a Cocoa project on the iPhone very easily.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-3323254146374043462?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/3323254146374043462/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=3323254146374043462" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/3323254146374043462?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/3323254146374043462?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html" title="Base64 encoding options on the Mac and iPhone" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUUEQnkycSp7ImA9WxJQE08.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-6742089833467832907</id><published>2009-05-25T23:15:00.001-07:00</published><updated>2009-05-26T00:33:23.799-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-26T00:33:23.799-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><title>Simple methods for date formatting and transcoding</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;There is no single-line method for converting between formatting date strings and date objects in Cocoa &amp;mdash; the API opts for flexibility rather than simplicity. Unfortunately, this combines with documentation that omits, misdirects and occasionally misinforms, making NSDateFormatter one of the more confusing classes for new Cocoa programmers. In this post, I'll try to address some of the documentation issues and I'll present some methods that will turn NSDate into a formatted string or convert between date strings in a single method.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Default, locale-based date formatting&lt;/h4&gt;
&lt;p&gt;Before I get into date formatting strings (which is the real purpose of this post) I will quickly show you how to get a string from an &lt;code&gt;NSDate&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
NSString *dateString = [dateFormatter stringFromDate:date];&lt;/pre&gt;

&lt;p&gt;This code formats the string according to the user's preferences set in the International General Settings (iPhone) or System Preferences (Mac OS X).&lt;/p&gt;

&lt;p&gt;Personally, I think this is verbose for such a common activity and normally use a category method on &lt;code&gt;NSDate&lt;/code&gt; to reduce it:&lt;/p&gt;

&lt;pre&gt;@implementation NSDate (FormattedStrings)
- (NSString *)dateStringWithStyle:(NSDateFormatterStyle)style
{
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setDateStyle:style];
    return [dateFormatter stringFromDate:self];
}
@end&lt;/pre&gt;

&lt;p&gt;This reduces the first code sample to:&lt;/p&gt;

&lt;pre&gt; NSString *dateString = [[NSDate date] dateStringWithStyle:NSDateFormatterLongStyle];&lt;/pre&gt;

&lt;p&gt;If you need time strings instead of date strings, create a &lt;code&gt;timeStringWithStyle:&lt;/code&gt; method by replacing the &lt;code&gt;setDateStyle:&lt;/code&gt; invocation with &lt;code&gt;setTimeStyle:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have read rants by other Objective-C programmers who hate seeing projects with hundreds of small categories for every little task.&lt;/p&gt;

&lt;p&gt;Frankly, I've never understood the objection. In fact, I think lots of small categories used to choose the settings you prefer on top of common interfaces is essential for establishing consistent aesthetics for your program &amp;mdash; your entire program will have the same style and you can easily update the aesthetic for the whole program by editing a single location.&lt;/p&gt;

&lt;p&gt;An example would be to replace this &lt;code&gt;dateStringWithStyle:&lt;/code&gt; method with a &lt;code&gt;dateStringWithProjectStyle&lt;/code&gt; method that returns the appropriately configured string for use throughout your program. One of your projects might use &lt;code&gt;NSDateFormatterLongStyle&lt;/code&gt; and the next might use a totally customized format (as I'll describe in the next sections) but you as a programmer can still invoke &lt;code&gt;dateStringWithProjectStyle&lt;/code&gt; everywhere you need a string from an &lt;code&gt;NSDate&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;Date formatting documentation issues&lt;/h4&gt;

&lt;p&gt;At its heart, &lt;code&gt;NSDateFormatter&lt;/code&gt; is very simple to use and yet it repeatedly baffles new users. I don't think this is really the fault of the API as much as the history behind it and the effect that it has had on the documentation.&lt;/p&gt;

&lt;p&gt;Despite &lt;code&gt;NSDateFormatterBehavior10_4&lt;/code&gt; being the only date formatting you should ever use and the only style that &lt;em&gt;should&lt;/em&gt; exist in the documentation, Apple's documentation has the following quirks:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;The actual syntax for &lt;code&gt;NSDateFormatterBehavior10_4&lt;/code&gt; is never given in the documentation and you can easily miss the links to &lt;a href="http://unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns"&gt;Unicode Standard (tr35)&lt;/a&gt; which describe it.&lt;/li&gt;
&lt;li&gt;A majority of the pages in the date formatting documentation seem concerned with the old &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt; style formatter behavior even though this is functionally deprecated.&lt;/li&gt;
&lt;li&gt;The documentation for &lt;code&gt;defaultFormatterBehavior&lt;/code&gt; claims &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt; is the default style but it is actually &lt;code&gt;NSDateFormatterBehavior10_4&lt;/code&gt; in Leopard and iPhoneSDK2.0.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, if you've been skimming through the documentation getting confused by the different styles, you may overlook one line at the top of the &lt;code&gt;NSDateFormatter&lt;/code&gt; API reference page:

&lt;blockquote&gt;&lt;strong&gt;iPhone OS Note:&lt;/strong&gt; iPhone OS supports only the modern 10.4+ behavior. 10.0-style methods and format strings are not available on iPhone OS.&lt;/blockquote&gt;

&lt;p&gt;All that documentation in the iPhone SDK concerned with the old &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt; style is completely meaningless &amp;mdash; &lt;em&gt;you can't use &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt; at all on the iPhone&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Adding to the iPhone frustration, &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt; will work in the simulator, causing headaches when code suddenly stops working on the device.&lt;/p&gt;

&lt;p&gt;On Mac OS X, even though you can use &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt;, it is deprecated for all practical purposes so you probably shouldn't. Annoyingly, since the documentation still claims &lt;code&gt;NSDateFormatterBehavior10_0&lt;/code&gt; is the default, you should explicitly set the formatter behavior to &lt;code&gt;NSDateFormatterBehavior10_4&lt;/code&gt; to remain safe &amp;mdash; at least until the documented default is updated to formally match the actual default.&lt;/p&gt;

&lt;p&gt;I don't mean to be cruel to Apple &amp;mdash; documentation is difficult, time consuming and annoying &amp;mdash; but I suspect these quirks in the documentation and behavior are responsible for a lot of confusion.&lt;/p&gt;

&lt;h4&gt;Date formatting syntax&lt;/h4&gt;

&lt;p&gt;Setting a date formatting string looks like this:&lt;/p&gt;

&lt;pre&gt;NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"dd MMM, yyyy"];
NSString *dateString = [dateFormatter stringFromDate:date];&lt;/pre&gt;

&lt;p&gt;This will create a string of the format "26 May, 2009". The arrangement of data in this string is determined by the format string passed to the &lt;code&gt;setDateFormat:&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;A quick summary of the date formatting options useable in this format string:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Character&lt;/td&gt;&lt;td&gt;Matches/Outputs&lt;/td&gt;&lt;td&gt;Multiples&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;y&lt;/td&gt;&lt;td&gt;Year&lt;/td&gt;&lt;td&gt;1, 2 or 4 'y's will show the value, 2 digit zero-padded value or 4 digit zero-padded value respectively&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;M&lt;/td&gt;&lt;td&gt;Month&lt;/td&gt;&lt;td&gt;1, 2, 3, 4 or 5 'M's will show the value, 2 digit zero-padded value, short name, long name or initial letter months&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;d&lt;/td&gt;&lt;td&gt;Day of Month&lt;/td&gt;&lt;td&gt;1 or 2 'd's will show the value or 2 digit zero-padded value representation respectively.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;e&lt;/td&gt;&lt;td&gt;Weekday&lt;/td&gt;&lt;td&gt;1, 2, 3, 4 or 5 'e's will show the value weekday number, 2 digit zero-padded value weekday number, short name, long name or initial letter respectively. Weekday numbers starts on Monday. Use uppercase 'E' for weekday numbers starting on Sunday.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;a&lt;/td&gt;&lt;td&gt;AM or PM&lt;/td&gt;&lt;td&gt;No repeat supported&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;h&lt;/td&gt;&lt;td&gt;Hour&lt;/td&gt;&lt;td&gt;1 or 2 'h's will show the value or 2 digit zero-padded value representation respectively. Use uppercase for 24 hour time.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;m&lt;/td&gt;&lt;td&gt;Minute&lt;/td&gt;&lt;td&gt;1 or 2 'm's will show the value or 2 digit zero-padded value representation respectively.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;s&lt;/td&gt;&lt;td&gt;Second&lt;/td&gt;&lt;td&gt;1 or 2 's's will show the value or 2 digit zero-padded value representation respectively.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;z&lt;/td&gt;&lt;td&gt;Timezone&lt;/td&gt;&lt;td&gt;1, 2, 3 or 4 'z's will show short acronym, short name, long acronym, long name respectively. Use uppercase to show GMT offset instead of name &amp;mdash; 1 or 2 digit zero-padded values shows GMT or RFC 822 respectively.&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Case is important &amp;mdash; using the wrong case can cause parsing to fail. Use lowercase by default for all values except Month.&lt;/p&gt;

&lt;p&gt;Alphabetic and numeric characters should be enclosed in single quotes (asterisk character) if you want them to pass through the parser as literal characters. A double asterisk will pass through as a single asterisk (self escaping). Most other punctuation and spaces will go through as normal except backslash which works like a normal C-string escape character to handle tabs, newlines and other special characters.&lt;/p&gt;

&lt;p&gt;For the complete specification, including the more obscure options that I haven't bothered to list, see &lt;a href="http://unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns"&gt;Unicode Standard (tr35)&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Date string transcoding&lt;/h4&gt;

&lt;p&gt;The date formatting options can also be used to parse strings. With parsing and output formatting, we can create a date string transcoder method in a category on &lt;code&gt;NSDateFormatter&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;+ (NSString *)dateStringFromString:(NSString *)sourceString
    sourceFormat:(NSString *)sourceFormat
    destinationFormat:(NSString *)destinationFormat
{
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:sourceFormat];
    NSDate *date = [dateFormatter dateFromString:sourceString];
    [dateFormatter setDateFormat:destinationFormat];
    return [dateFormatter stringFromDate:date];
}&lt;/pre&gt;

&lt;p&gt;We can use this method to convert one date string (for example "2007-08-11T19:30:00Z") into another ("7:30:00PM on August 11, 2007") in the following manner:&lt;/p&gt;

&lt;pre&gt;NSString *inputDateString = @"2007-08-11T19:30:00Z";
NSString *outputDateString = [NSDateFormatter
    dateStringFromString:inputDateString
    sourceFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"
    destinationFormat:@"h:mm:ssa 'on' MMMM d, yyyy"];&lt;/pre&gt;

&lt;h4&gt;Calendar stuff&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;NSDateFormatter&lt;/code&gt; class is just for parsing and formatting strings. You shouldn't use it to build dates from their components or to decompose dates into components. For that task, use &lt;code&gt;NSCalendar&lt;/code&gt;. It's a little outside the scope of this post but since I know it will come up, here's how to set an &lt;code&gt;NSDate&lt;/code&gt; to the 26th of May, 2009 using &lt;code&gt;NSCalendar&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
[components setDay:26];
[components setMonth:5];
[components setYear:2009];
NSCalendar *gregorian =
    [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDate *date = [gregorian dateFromComponents:components];&lt;/pre&gt;

&lt;p&gt;To get the components from a date, use:&lt;/p&gt;

&lt;pre&gt;unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
NSDate *date = [NSDate date];
NSCalendar *gregorian =
    [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *components = [gregorian components:unitFlags fromDate:date];&lt;/pre&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;As I've said a few times now, the actual API for date formatting in Cocoa is simple. The only reason why I consider it a topic worthy of a post is that I still see at least one question a week on &lt;a href="http://stackoverflow.com"&gt;StackOverflow&lt;/a&gt; and other forums asking why &lt;code&gt;NSDateFormatter&lt;/code&gt; is failing in their code and the answer is normally because their code confuses the formatting behaviors, uses the wrong format specifiers or has otherwise misunderstood the required steps.&lt;/p&gt;

&lt;p&gt;I hope what I've presented clears up these issues. Date formatting should be simple enough that you can write it once and never worry about it again.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-6742089833467832907?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/6742089833467832907/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=6742089833467832907" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/6742089833467832907?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/6742089833467832907?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/05/simple-methods-for-date-formatting-and.html" title="Simple methods for date formatting and transcoding" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUAAQnYyfip7ImA9WxJRGEU.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-8741917226850532685</id><published>2009-05-19T22:10:00.001-07:00</published><updated>2009-05-20T23:35:43.896-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-20T23:35:43.896-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><category scheme="http://www.blogger.com/atom/ns#" term="UIKit" /><category scheme="http://www.blogger.com/atom/ns#" term="fun hacks" /><title>Intercepting status bar touches on the iPhone</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;You can configure your iPhone applications so that a touch in the status bar will scroll a UIScrollView to the top. I'll show you how you can intercept this touch event to use status bar touches for other purposes. The sample application will show a hidden drawer that slides out from the status bar when you tap it.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Touches in the status bar&lt;/h4&gt;
&lt;p&gt;A lesser known user-interface feature on the iPhone is that touches in the status bar will usually scroll the main &lt;code&gt;UIScrollView&lt;/code&gt; to the top, providing a quick way to scroll to the top of long documents.&lt;/p&gt;

&lt;p&gt;This will work in your application when exactly one &lt;code&gt;UIScrollView&lt;/code&gt; returns &lt;code&gt;YES&lt;/code&gt; for the &lt;code&gt;scrollsToTop&lt;/code&gt; property (&lt;code&gt;YES&lt;/code&gt; is the default). If more than one &lt;code&gt;UIScrollView&lt;/code&gt; returns &lt;code&gt;YES&lt;/code&gt; for this property (or the &lt;code&gt;UIScrollView&lt;/code&gt;'s &lt;code&gt;delegate&lt;/code&gt; returns &lt;code&gt;NO&lt;/code&gt; from &lt;code&gt;scrollViewWillScrollToTop:&lt;/code&gt;) the scroll to top functionality will be disabled.&lt;/p&gt;

&lt;p&gt;That's the ordinary functionality but how do we achieve different functionality?&lt;/p&gt;

&lt;h4&gt;The HiddenDrawer sample appliction&lt;/h4&gt;

&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/ShOAKWTE1aI/AAAAAAAAATA/zuMnrp2zRnM/hidden_drawer_screenshots.png?imgmax=800" alt="hidden_drawer_screenshots.png" border="0" width="500" height="220" /&gt;

&lt;p&gt;These screenshots show the HiddenDrawer sample application. When the status bar is tapped on the left, the hidden drawer animates out from under the status bar, resulting in the state shown on the right.&lt;/p&gt;

&lt;h4&gt;Stealing status bar touch events&lt;/h4&gt;

&lt;p&gt;The trickiest part of the sample application is detecting a touch in the status bar.&lt;/p&gt;

&lt;p&gt;By implementing a custom &lt;code&gt;setContentOffset:animated:&lt;/code&gt; method on a &lt;code&gt;UITableView&lt;/code&gt; and setting a breakpoint in that method, you can see in the debugger stack that the &lt;code&gt;UIApplication&lt;/code&gt; &lt;code&gt;sendEvent:&lt;/code&gt; method is invoked for status bar touches, so that's where we'll begin.&lt;/p&gt;

&lt;h5&gt;CustomApplication&lt;/h5&gt;

&lt;p&gt;Overriding &lt;code&gt;UIApplication&lt;/code&gt; is extremely rare so I'll explain how to make it work. Once you create the subclass of &lt;code&gt;UIApplication&lt;/code&gt; you need to tell the program to use that subclass. In Cocoa Senior (Mac OS X) you specify application subclasses in the Info.plist file. In Cocoa Touch, you specify custom application subclasses by name in the &lt;code&gt;UIApplicationMain&lt;/code&gt; function in the &lt;code&gt;main.m&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;int retVal = UIApplicationMain(argc, argv, @"CustomApplication", nil);&lt;/pre&gt;


&lt;h5&gt;sendEvent:&lt;/h5&gt;

&lt;p&gt;The only method override we need in &lt;code&gt;CustomApplication&lt;/code&gt; is &lt;code&gt;sendEvent:&lt;/code&gt;. The difficult part is then working out from the &lt;code&gt;UIEvent&lt;/code&gt; which events are status bar touch events &amp;mdash; unfortunately, the &lt;code&gt;allTouches&lt;/code&gt; method returns an empty array for status bar touches.&lt;/p&gt;

&lt;p&gt;Instead, we delve into the secret &lt;code&gt;GSEvent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I previously accessed &lt;code&gt;GSEvent&lt;/code&gt; in my post &lt;a href="http://cocoawithlove.com/2008/10/synthesizing-touch-event-on-iphone.html"&gt;Synthesizing a touch event on the iPhone&lt;/a&gt;. In that post, I created a &lt;code&gt;PublicEvent&lt;/code&gt; class and a fake &lt;code&gt;GSEventProxy&lt;/code&gt; class to access the required fields. This time, I'm going to use a different approach and jump straight to the data I need.&lt;/p&gt;

&lt;pre&gt;- (void)sendEvent:(UIEvent *)anEvent
{
    #define GS_EVENT_TYPE_OFFSET 2
    #define GS_EVENT_X_OFFSET 6
    #define GS_EVENT_Y_OFFSET 7
    #define STATUS_BAR_TOUCH_DOWN 1015
    
    &lt;strong&gt;// Traverse from the UIEvent to the GSEvent to the type&lt;/strong&gt;
    int *eventMemory = (int *)[anEvent performSelector:@selector(_gsEvent)];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];

    &lt;strong&gt;// Look for status bar touches by event type&lt;/strong&gt;
    if (eventType == STATUS_BAR_TOUCH_DOWN)
    {
        &lt;strong&gt;// The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are:&lt;/strong&gt; 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];

        typedef union {int intValue; float floatValue;} Int2Float;
        float x = ((Int2Float)xMemory).floatValue;
        float y = ((Int2Float)yMemory).floatValue;

        NSLog(@"Status bar down at %f, %f", x, y);
        
        &lt;strong&gt;// Send a message to the delegate to handle the action&lt;/strong&gt;
        [(HiddenDrawerAppDelegate *)self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
}&lt;/pre&gt;

&lt;p&gt;You may be curious to know where the &lt;code&gt;OFFSET&lt;/code&gt; values come from. The answer is that I spent a while staring at the raw memory values in the &lt;code&gt;GSEvent&lt;/code&gt; object while deliberately causing status bar and other touch events &amp;mdash; nothing fancier than that. It's tricky and unreliable. If it works at all in iPhoneSDK3.0, it'll be pure luck.&lt;/p&gt;

&lt;p&gt;I also use a &lt;code&gt;union&lt;/code&gt; here. This is because I step through memory as &lt;code&gt;int&lt;/code&gt;s and in C, a basic cast from &lt;code&gt;int&lt;/code&gt; to &lt;code&gt;float&lt;/code&gt; causes a value conversion (I want a reinterpret, not a value conversion).&lt;/p&gt;

&lt;p&gt;I also chose to suppress status bar touch events going through to the &lt;code&gt;UITableView&lt;/code&gt; by the normal route. If you want to re-enable this behavior, you can take the &lt;code&gt;[super sendEvent:anEvent];&lt;/code&gt; line out of the &lt;code&gt;else&lt;/code&gt; block and put it in the main method body.&lt;/p&gt;

&lt;h4&gt;Animating the drawer&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;sendEvent:&lt;/code&gt; implementation above invokes the &lt;code&gt;toggleDrawer&lt;/code&gt; method on the application's &lt;code&gt;delegate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All that's required is to animate the drawer's view in and push the table's view down:&lt;/p&gt;

&lt;pre&gt;drawerController = [[HiddenDrawerViewController alloc] init];

&lt;strong&gt;// Position the drawer below the status bar&lt;/strong&gt;
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;

&lt;strong&gt;// For the animation, move the drawer up by its own height.&lt;/strong&gt;
drawerFrame.origin.y -= drawerFrame.size.height;

&lt;strong&gt;// Place the drawer and add it to the window&lt;/strong&gt;
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];

&lt;strong&gt;// Start the animation&lt;/strong&gt;
[UIView beginAnimations:nil context:nil];

&lt;strong&gt;// Move the table down&lt;/strong&gt;
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;

&lt;strong&gt;// Move the drawer down&lt;/strong&gt;
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;

&lt;strong&gt;// Commit the animation&lt;/strong&gt;
[UIView commitAnimations];&lt;/pre&gt;

&lt;p&gt;If you download the whole project, you'll see that there's also an animate up and remove branch that gets run if the &lt;code&gt;drawerController&lt;/code&gt; already exists.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the &lt;a href="http://cocoawithlove.googlepages.com/HiddenDrawer.zip"&gt;HiddenDrawer sample project&lt;/a&gt; (30kB) to see the whole application in action.&lt;/blockquote&gt;

&lt;p&gt;A hidden drawer under the status bar isn't necessarily something that every iPhone application should have but the obscure, secretive nature of it appeals to me.&lt;/p&gt;

&lt;p&gt;The approach of determining which &lt;code&gt;UIEvent&lt;/code&gt; we want by the &lt;code&gt;type&lt;/code&gt; field in the &lt;code&gt;GSEvent&lt;/code&gt; is a little precarious. Apple are free to change the structure of &lt;code&gt;GSEvent&lt;/code&gt; at any time, which could cause your application to misbehave or crash so this type of code would need to be tested on each iPhone OS release to ensure that it still works.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-8741917226850532685?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/8741917226850532685/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=8741917226850532685" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/8741917226850532685?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/8741917226850532685?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/05/intercepting-status-bar-touches-on.html" title="Intercepting status bar touches on the iPhone" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUIGR3s7fCp7ImA9WxJREE4.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-6477759699030925020</id><published>2009-05-10T20:05:00.001-07:00</published><updated>2009-05-11T02:18:46.504-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-11T02:18:46.504-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Objective-C" /><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><category scheme="http://www.blogger.com/atom/ns#" term="Standard C" /><title>Variable argument lists in Cocoa</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;This week I'll talk about methods that take variable numbers of arguments, also known as variadic methods. I'll show you the Objective-C syntax and implementation, give a quick rundown of the ways that Cocoa classes provide variable argument support and I'll also show you a way to fake va_list parameters to handle Cocoa's variadic method equivalents at runtime.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Variable arguments basics&lt;/h4&gt;
&lt;p&gt;Passing a variable number of arguments to a method is a convenient way to handle a list of variables that are in scope at compile time.&lt;/p&gt;

&lt;p&gt;The Objective-C language handles variable arguments in the same way that Standard C does. Normally, you will encounter variable argument lists in one of two forms: "Format strings" or "Nil terminated lists".&lt;/p&gt;

&lt;h5&gt;Format strings&lt;/h5&gt;

&lt;p&gt;The traditional example for variable arguments are format strings. Format strings contain a number of "placeholders" (escape sequences starting with a "%" sign) that are replaced with data from variables when the format string and the variable arguments are passed to the method.&lt;/p&gt;

&lt;pre&gt;NSString *myString = [NSString stringWithFormat:
    @"Number %d, String: %@, Float: %g", 123, @"SomeString", 34.5];&lt;/pre&gt;

&lt;p&gt;This method is declared as follows:&lt;/p&gt;

&lt;pre&gt;+ (id)stringWithFormat:(NSString *)format, ...;&lt;/pre&gt;

&lt;p&gt;The "..." is the variable argument.&lt;/p&gt;

&lt;p&gt;This method declares a first parameter but everything else is "variable". This does not mean optional. Instead, it means that a number of extra parameters will be required. Exactly what number and their types depends on how the method works.&lt;/p&gt;

&lt;p&gt;The documented behavior for &lt;code&gt;stringWithFormat:&lt;/code&gt;, is that it scans the &lt;code&gt;format&lt;/code&gt; string and requires 1 variable argument for every escape sequence (in this case there are 3) and the type must match the specifier for each escape sequence (in this case, "d", "@" and "g" specify &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;float&lt;/code&gt;/&lt;code&gt;double&lt;/code&gt;).&lt;/p&gt;

&lt;h5&gt;Nil terminated lists&lt;/h5&gt;

&lt;p&gt;The other common type of variable argument list method is one that takes a list of objects terminated by nil.&lt;/p&gt;

&lt;p&gt;In Cocoa, these are commonly used for constructing collection objects.&lt;/p&gt;

&lt;pre&gt;NSArray *myArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];&lt;/pre&gt;

&lt;p&gt;The documented rule for this type of method is that the last argument must be &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;Getting argument numbers wrong&lt;/h5&gt;

&lt;p&gt;The details of "Format strings" and "Nil terminated lists" reveal the difficulty with variable argument lists in Objective-C: knowing how many arguments exist &amp;mdash; i.e. when to stop reading arguments.&lt;/p&gt;

&lt;p&gt;Objective-C, like C, does not have a runtime argument count, nor does it pass runtime argument types. So the number and types of arguments must be determined by some other policy. In the case of these two examples, the argument count is, respectively: the number of escape sequences in the "Format string" or the number of arguments before the first &lt;code&gt;nil&lt;/code&gt;. For "format strings" the types are determined by the escape sequences, for "Nil terminated" lists, the arguments are always pointers.&lt;/p&gt;

&lt;p&gt;The penalty for getting variable argument list wrong can be severe: the compiler won't typically notice a problem and your code will crash or behave very strangely at runtime. The important lesson to learn is that you should only use variable arguments in a situation where the policy for numbers and types of arguments is very clear.&lt;/p&gt;

&lt;blockquote&gt;You can improve the compiler verification of variable argument lists by using the &lt;code&gt;-Wformat&lt;/code&gt; compiler flag in GCC. See below for more about how this works.&lt;/blockquote&gt;

&lt;h4&gt;Implementing variable arguments for your own methods&lt;/h4&gt;

&lt;p&gt;Lets look at the implementation for the example class:&lt;/p&gt;

&lt;pre&gt;@interface StringContainer : NSObject
{
    NSString *contents;
}
@end&lt;/pre&gt;

&lt;p&gt;Imagine we wanted a method that would set the &lt;code&gt;contents&lt;/code&gt; string this class contains by concatenating a variable argument list of strings together.&lt;/p&gt;

&lt;p&gt;In this case, we will use the &lt;code&gt;nil&lt;/code&gt; terminated approach &amp;mdash; the list of strings to concatenate will end with a &lt;code&gt;nil&lt;/code&gt;, so we know when to stop reading.&lt;/p&gt;

&lt;p&gt;The declaration for the method looks like this:&lt;/p&gt;

&lt;pre&gt;- (void)setContentByAppendingStrings:(NSString *)firstString, ...
    NS_REQUIRES_NIL_TERMINATION;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;NS_REQUIRES_NIL_TERMINATION&lt;/code&gt; part is a macro that tells the compiler that invocations of this method must include a &lt;code&gt;nil&lt;/code&gt;-terminated list of arguments. Failure to &lt;code&gt;nil&lt;/code&gt;-terminate the list will result in a compiler warning if &lt;code&gt;-Wformat&lt;/code&gt; is enabled.&lt;/p&gt;

&lt;p&gt;Annoyingly, &lt;code&gt;-Wformat&lt;/code&gt; is not enabled by default. Double annoyingly, it is named "Typecheck Calls to printf/scanf" in the "GCC 4.0 Warnings" section of the "Build Settings" in Xcode, even though this setting affects the &lt;code&gt;NS_REQUIRES_NIL_TERMINATION&lt;/code&gt; macro which is used commonly throughout all of Cocoa &amp;mdash; far beyond &lt;code&gt;printf&lt;/code&gt; and &lt;code&gt;scanf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The implementation of this method is as follows:&lt;/p&gt;

&lt;pre&gt;- (void)setContentByAppendingStrings:(NSString *)firstArg, ...
{
    NSMutableString *newContentString = [NSMutableString string];
    va_list args;
    va_start(args, firstArg);
    for (NSString *arg = firstArg; arg != nil; arg = va_arg(args, NSString*))
    {
        [newContentString appendString:arg];
    }
    va_end(args);
    
    [contents autorelease];
    contents = [newContentString retain];
}&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;va_list&lt;/code&gt;, &lt;code&gt;va_start&lt;/code&gt;, &lt;code&gt;va_arg&lt;/code&gt; and &lt;code&gt;va_end&lt;/code&gt; are all standard C syntax for handling variable arguments. To describe them simply:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;va_list&lt;/code&gt; - A pointer to a list of variable arguments.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;va_start&lt;/code&gt; - Initializes a &lt;code&gt;va_list&lt;/code&gt; to point to the first argument &lt;em&gt;after&lt;/em&gt; the argument specified.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;va_arg&lt;/code&gt; - Fetches the next argument out of the list. You must specify the type of the argument (so that &lt;code&gt;va_arg&lt;/code&gt; knows how many bytes to extract).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;va_end&lt;/code&gt; - Releases any memory held by the &lt;code&gt;va_list&lt;/code&gt; data structure.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Generally speaking, you can use this &lt;code&gt;for&lt;/code&gt; loop for any variable argument situation where your arguments are all the same type. Other cases are a bit trickier but far less common &amp;mdash; I'm sure you can work out how they would work if needed.&lt;/p&gt;

&lt;h4&gt;va_list in Cocoa&lt;/h4&gt;

&lt;p&gt;A number of classes in Cocoa have methods that take variable numbers of arguments. In most cases, these classes will also have an equivalent method that takes a &lt;code&gt;va_list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can see an example of these &lt;code&gt;va_list&lt;/code&gt; equivalents by looking at &lt;code&gt;NSString&lt;/code&gt;. &lt;code&gt;NSString&lt;/code&gt; declares the class method &lt;code&gt;stringWithFormat:...&lt;/code&gt; (which takes a variable number of arguments) and &lt;code&gt;NSString&lt;/code&gt; also declares the instance method &lt;code&gt;initWithFormat:arguments:&lt;/code&gt; (where the &lt;code&gt;arguments&lt;/code&gt; parameter is a &lt;code&gt;va_list&lt;/code&gt;) which handles the equivalent behavior of &lt;code&gt;stringWithFormat:...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These &lt;code&gt;va_list&lt;/code&gt; methods are used in the situation where your class defines a method with a variable argument list and you need to pass those variable arguments into the Cocoa method. For example, if the &lt;code&gt;StringContainer&lt;/code&gt; class listed above declared the method:&lt;/p&gt;

&lt;pre&gt;- (void)setContentsWithFormat:(NSString *)formatString, ...;&lt;/pre&gt;

&lt;p&gt;The implementation of this method would be as follows:&lt;/p&gt;

&lt;pre&gt;- (void)setContentsWithFormat:(NSString *)formatString, ...
{
    [contents autorelease];

    va_list args;
    va_start(args, formatString);
    contents = [[NSString alloc] initWithFormat:formatString arguments:args];
    va_end(args);
}&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;va_list&lt;/code&gt; parameter allows us to pass our own variable argument list to the Cocoa method so that the Cocoa method can handle the arguments.&lt;/p&gt;

&lt;h4&gt;Creating a fake va_list&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;va_list&lt;/code&gt; methods in Cocoa are helpful if you actually have a variable argument list. &lt;/p&gt;

&lt;p&gt;There is another situation you many encounter though: you want to use a method like &lt;code&gt;-[NSString initWithFormat:arguments:]&lt;/code&gt; using a runtime generated array of arguments. There is no &lt;code&gt;NSString&lt;/code&gt; format method that takes an &lt;code&gt;NSArray&lt;/code&gt; of arguments, so how could we handle a format string at runtime?&lt;/p&gt;

&lt;p&gt;The answer lies in how &lt;code&gt;va_list&lt;/code&gt; works. While GCC makes it very clear that &lt;code&gt;va_list&lt;/code&gt; is "platform specific", the reality is that on Mac and iPhone Objective-C platforms, it is simply a byte buffer containing the arguments. In fact, if you've ever used an ABI inspection tool (like &lt;a href="http://iphone.freecoder.org/classdump_en.html"&gt;class-dump-x&lt;/a&gt;) on a method taking a variable argument list, you'll see that it is simply a &lt;code&gt;char *&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To show how we can use this knowledge, consider the following method on the &lt;code&gt;StringContainer&lt;/code&gt; class:&lt;/p&gt;

&lt;pre&gt;- (void)setContentsWithFormat:(NSString *)formatString arguments:(NSArray *)arguments;&lt;/pre&gt;

&lt;p&gt;If we assume that all of the variable arguments required fro the &lt;code&gt;formatString&lt;/code&gt; are objects, then we can implement this method as follows:&lt;/p&gt;

&lt;pre&gt;- (void)setContentsWithFormat:(NSString *)formatString arguments:(NSArray *)arguments
{
    [contents autorelease];

    char *argList = (char *)malloc(sizeof(NSString *) * [arguments count]);
    [arguments getObjects:(id *)argList];
    
    contents = [[NSString alloc] initWithFormat:formatString arguments:argList];
    
    free(argList);
}&lt;/pre&gt;

&lt;p&gt;What I've done here is simply copied the &lt;code&gt;NSArray&lt;/code&gt; to a C-style byte buffer and then passed that buffer to the &lt;code&gt;initWithFormat:arguments:&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;If your arguments are not all Objective-C objects, you'd need to take greater care to assemble the byte buffer but the principles would be the same.&lt;/p&gt;

&lt;h4&gt;Some variadic notes&lt;/h4&gt;

&lt;h5&gt;NSInvcation incompatibility&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;NSInvocation&lt;/code&gt; does not support variadic methods. I'm not sure why this is &amp;mdash; maybe &lt;code&gt;NSInvocation&lt;/code&gt; wants to avoid making assumptions about &lt;code&gt;va_list&lt;/code&gt;, maybe it is because &lt;code&gt;NSMethodSignature&lt;/code&gt; can't describe the storage requirements of variable arguments for &lt;code&gt;NSInvocation&lt;/code&gt; or maybe the Cocoa developers have families and just wanted to go home early.&lt;/p&gt;

&lt;h5&gt;Variadic macros&lt;/h5&gt;

&lt;p&gt;You can also write variadic macros, much like variadic methods, by using the &lt;code&gt;##__VA_ARGS__&lt;/code&gt; placeholder in your macros. See the macros near the bottom of my post titled &lt;a href="http://cocoawithlove.com/2008/03/supersequent-implementation.html"&gt;Supersequent Implementation&lt;/a&gt; for an example of how this works. As discussed briefly in that article, the version of GCC used for iPhone development handles variadic macros slightly differently, so pay attention to the differences when targetting the iPhone platform.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;Variadic methods require a degree more care than regular methods because variable argument lists have no "introspection" (you cannot ask for the number and type of arguments) &amp;mdash; so their usage relies on documentation and implicit agreements between the sender and receiver.&lt;/p&gt;

&lt;p&gt;In your own code, variadic methods should be used sparingly &amp;mdash; passing variables in an &lt;code&gt;NSArray&lt;/code&gt; or &lt;code&gt;NSDictionary&lt;/code&gt; is safer (if slightly slower and syntactically more verbose) due to the fact that these classes &lt;em&gt;do&lt;/em&gt; offer introspection.&lt;/p&gt;

&lt;p&gt;When the implicit sender/receiver agreement is clear, variadic methods work well. They certainly make creating instances of &lt;code&gt;NSArray&lt;/code&gt;, &lt;code&gt;NSSet&lt;/code&gt;, &lt;code&gt;NSDictionary&lt;/code&gt; easier and they are the only way to create a formatted &lt;code&gt;NSString&lt;/code&gt; in a single invocation.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-6477759699030925020?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/6477759699030925020/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=6477759699030925020" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/6477759699030925020?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/6477759699030925020?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html" title="Variable argument lists in Cocoa" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;AkcDQXg8eyp7ImA9WxJSFkU.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-5472158567100919144</id><published>2009-05-04T19:37:00.001-07:00</published><updated>2009-05-07T02:21:10.673-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-07T02:21:10.673-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><category scheme="http://www.blogger.com/atom/ns#" term="AppKit" /><title>Invoking other processes in Cocoa</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Invoking other processes is a good way to handle some low-level tasks on the Mac. I'll show you some simple ways to invoke processes and parse their outputs in Cocoa apps as well as some advanced tricks like running a process with administrator privileges.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;The Sample Application: Open File Killer&lt;/h4&gt;
&lt;p&gt;Have you ever tried to empty the Trash, only to be told that some process has one of the files open so Trash can't delete it now?&lt;/p&gt;

&lt;p&gt;This week's sample application solves that problem. Drag a file onto Open File Killer and it will tell you all the processes that have the file open and lets you kill them if needed.&lt;/p&gt;

&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/Sf7ckpCIxnI/AAAAAAAAAS4/tUgXFRy3K_Y/openfilekiller.png?imgmax=800" alt="openfilekiller.png" border="0" width="482" height="300" /&gt;

&lt;h4&gt;How Open File Killer works&lt;/h4&gt;

&lt;p&gt;This program invokes two other processes to perform its work:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;lsof - to find the processes that have the specified file open&lt;/li&gt;
&lt;li&gt;sh - run with administrator privileges to send a SIGKILL to processes&lt;/li&gt;&lt;/ul&gt;

&lt;blockquote&gt;Be careful when using the "Kill process" button &amp;mdash; arbitrarily killing system processes can be dangerous to data and system stability so use with caution.&lt;/blockquote&gt;

&lt;h4&gt;Starting another process with NSTask&lt;/h4&gt;

&lt;p&gt;You can launch other applications using &lt;code&gt;NSWorkspace&lt;/code&gt;'s &lt;code&gt;launchApplication:&lt;/code&gt; and they will appear as though you launched them from the Finder. To run processes that are not applications, you will typically use &lt;code&gt;NSTask&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NSTask&lt;/code&gt; does provide the convenience method &lt;code&gt;launchedTaskWithLaunchPath:arguments:&lt;/code&gt; to launch another process in one line, however this method does not allow access to the launched task's standard output, which we'll need to get results from &lt;code&gt;lsof&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Reading output from &lt;code&gt;NSTask&lt;/code&gt; requires setting up &lt;code&gt;NSPipe&lt;/code&gt;s and reading from the &lt;code&gt;NSFileHandle&lt;/code&gt; for each pipe. Since all this can be a bit verbose, we'll create a reusable method with the following prototype:&lt;/p&gt;

&lt;pre&gt;+ (NSString *)stringByLaunchingPath:(NSString *)processPath
    withArguments:(NSArray *)arguments
    error:(NSError **)error&lt;/pre&gt;

&lt;p&gt;This is similar to &lt;code&gt;launchedTaskWithLaunchPath:arguments:&lt;/code&gt; but returns the standard out as a string and returns standard error in the &lt;code&gt;userInfo&lt;/code&gt; property of the &lt;code&gt;NSError&lt;/code&gt; under the key &lt;code&gt;@"standardError"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Excluding the error handling parts, the implementation of this method is as follows:&lt;/p&gt;

&lt;pre&gt;NSTask *task = [[[NSTask alloc] init] autorelease];

[task setLaunchPath:processPath];
[task setArguments:arguments];
[task setStandardOutput:[NSPipe pipe]];
[task setStandardError:[NSPipe pipe]];

TaskOutputReader *outputReader = [[TaskOutputReader alloc] initWithTask:task];

NSString *outputString = nil;
NSString *errorString = nil;

[outputReader launchTaskAndRunSynchronous];

outputString =
    [[[NSString alloc]
        initWithData:[outputReader standardOutputData]
        encoding:NSUTF8StringEncoding]
    autorelease];
errorString =
    [[[NSString alloc]
        initWithData:[outputReader standardErrorData]
        encoding:NSUTF8StringEncoding]
    autorelease];

[outputReader release];&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;TaskOutputReader&lt;/code&gt; is a simple class that invokes &lt;code&gt;launch&lt;/code&gt; on the task and runs the current &lt;code&gt;NSRunLoop&lt;/code&gt;, reading from the standardOut and standardError of the task until the task terminates.&lt;/p&gt;

&lt;p&gt;The strangest part to me is the &lt;code&gt;NSPipe&lt;/code&gt; part &amp;mdash; &lt;code&gt;NSPipe&lt;/code&gt; is an opaque class (you can't do anything directly to it) that only works with &lt;code&gt;NSTask&lt;/code&gt; and allows you to subsequently invoke &lt;code&gt;fileHandleForReading&lt;/code&gt;/&lt;code&gt;fileHandleForWriting&lt;/code&gt;. To me, it really seems as though &lt;code&gt;NSPipe&lt;/code&gt; shouldn't exist at all and any Unix-level pipes and file descriptors should be created on demand when you invoke &lt;code&gt;standardOutput&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, that's why I always use a convenience method to wrap it all up. The only reason why you shouldn't use a convenience method like this is if you want progressive output updates (like line-by-line log file output) or two-way communication (command and response) since you can't simply block a return to the calling function these cases.&lt;/p&gt;

&lt;h4&gt;Parsing text&lt;/h4&gt;

&lt;p&gt;So we can use the &lt;code&gt;stringByLaunchingPath:withArguments:error:&lt;/code&gt; method to launch &lt;code&gt;lsof&lt;/code&gt; and pass the path of the file.&lt;/p&gt;

&lt;p&gt;The result from &lt;code&gt;lsof&lt;/code&gt; looks something like this:&lt;/p&gt;

&lt;pre&gt;COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
Preview 78180 matt  txt    REG   14,2    52889 1233935 /Users/matt/Downloads/002dfwtw.jpg&lt;/pre&gt;

&lt;p&gt;We need to parse this result and extract the information that is useful to us: the first two columns of the second row. I know, there are arguments to &lt;code&gt;lsof&lt;/code&gt; that will produce more "computer-readable" output but when done right, parsing this output should be easier than reading man-page documentation.&lt;/p&gt;

&lt;p&gt;The base Cocoa classes do no really handle sophisticated text parsing on their own. There is no regular expression library by default (get yourself a copy of &lt;a href="http://www8.ocn.ne.jp/%7esonoisa/OgreKit/index.html"&gt;OgreKit&lt;/a&gt; or &lt;a href="http://regexkit.sourceforge.net/"&gt;RegexKit&lt;/a&gt; to do that) and while &lt;code&gt;NSString&lt;/code&gt; has a few manipulation methods, many of the chop, split, tokenize and line-at-a-time handling functions and operators that are common in scripting languages, do not appear in Cocoa.&lt;/p&gt;

&lt;p&gt;You can guess at the reason behind some of these decisions. I would suggest that you're not supposed to store structured data in pure text strings in a language with sophisticated &lt;em&gt;real&lt;/em&gt; data structures, so Cocoa doesn't try to make it easier for you.&lt;/p&gt;

&lt;p&gt;Another reason would be that C-based languages are more about giving you the basic building blocks to make efficient solutions over any domain, not about giving you already-domain-specific pre-canned solutions. AppKit/UIKit are obvious exceptions where complete, domain-specific solutions are given but in those cases, the solution domain for "application framework" is already fixed (Mac OS X/iPhone), so they are not really narrowing the potential solutions.&lt;/p&gt;

&lt;p&gt;The result though, is that any project requiring text handling will likely need to implement a few simple text handling methods. You can get quite practised at using the "basic building blocks" to write small parser methods to handle data that comes from plain text sources like &lt;code&gt;lsof&lt;/code&gt;'s output.&lt;/p&gt;

&lt;pre&gt;- (NSArray *)arrayBySeparatingIntoParagraphs
{
    NSUInteger length = [self length];
    NSUInteger paraStart = 0;
    NSUInteger paraEnd = 0;
    NSUInteger contentsEnd = 0;
    NSMutableArray *array = [NSMutableArray array];
    NSRange currentRange;
    while (paraEnd &lt; length)
    {
        [self
            getParagraphStart:&amp;paraStart
            end:&amp;paraEnd
            contentsEnd:&amp;contentsEnd
            forRange:NSMakeRange(paraEnd, 0)];
        currentRange = NSMakeRange(paraStart, contentsEnd - paraStart);
        [array addObject:[self substringWithRange:currentRange]];
    }
    return array;
}&lt;/pre&gt;

&lt;p&gt;You might ask about this function: "Why not just use the existing &lt;code&gt;componentsSeparatedByString:&lt;/code&gt; and pass &lt;code&gt;@"\n"&lt;/code&gt; as the string?"&lt;/p&gt;

&lt;p&gt;The answer is largely because it is recommended that you don't assume &lt;code&gt;\n&lt;/code&gt; is the paragraph separator in case the paragraph separator is a Windows line-feed (&lt;code&gt;\r\n&lt;/code&gt;) or an old &lt;code&gt;Mac OS 9&lt;/code&gt; carriage return (&lt;code&gt;\r&lt;/code&gt;). Okay, irrelevant here but this method can be used &lt;em&gt;anywhere&lt;/em&gt; where you need to break an &lt;code&gt;NSString&lt;/code&gt; into paragraphs.&lt;/p&gt;

&lt;p&gt;Also, if you needed to optimize your code, &lt;code&gt;getParagraphStart:end:contentsEnd:forRange:&lt;/code&gt; allows you to parse each line inside the  loop, avoiding the need to create the array of lines at all. This is something that the upcoming "blocks" feature of Objective-C will make much easier since you'll be able to pass the block for the inside of the loop as a parameter to the method.&lt;/p&gt;

&lt;p&gt;You might also be curious about the difference between a "paragraph" and a "line", especially since the method &lt;code&gt;getLineStart:end:contentsEnd:forRange:&lt;/code&gt; also exists. The difference is minor &amp;mdash; lines also break on the rarely seen Unicode line-break character (sometimes used to represent HTML's &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt;). In this case, it doesn't really matter.&lt;/p&gt;

&lt;pre&gt;- (NSArray *)tokensSeparatedByCharactersInSet:(NSCharacterSet *)separator
{
    NSScanner *scanner = [NSScanner scannerWithString:self];
    NSMutableArray *array = [NSMutableArray array];
    while (![scanner isAtEnd])
    {
        [scanner scanCharactersFromSet:separator intoString:nil];

        NSString *component;
        if ([scanner scanUpToCharactersFromSet:separator intoString:&amp;component])
        {
            [array addObject:component];
        }
    }
    return array;
}&lt;/pre&gt;

&lt;p&gt;This method extracts runs of characters not in the separator character set from runs of characters that are. It differs from &lt;code&gt;componentsSeparatedByCharactersInSet:&lt;/code&gt; because it treats runs of separator characters as single elements and never outputs empty tokens.&lt;/p&gt;

&lt;p&gt;If we pass &lt;code&gt;[NSCharacterSet whitespaceCharacterSet]&lt;/code&gt; into this method, it will break the string up by blocks of whitespace, allowing us to extract the columns of text from a row of the &lt;code&gt;lsof&lt;/code&gt; output (where the rows are extracted using the &lt;code&gt;arrayBySeparatingIntoParagraphs&lt;/code&gt; method).&lt;/p&gt;

&lt;blockquote&gt;This method isn't used in the sample app anymore. It didn't handle application names with spaces in them. I've replaced it with an approach that extracts the columns from the &lt;code&gt;lsof&lt;/code&gt; output by character index using &lt;code&gt;substringWithRange:&lt;/code&gt; and then uses the &lt;code&gt;stringByTrimmingCharactersInSet:&lt;/code&gt; method to remove whitespace from the end. I'll leave the method in the post &amp;mdash; it is still useful, just not in this case.&lt;/blockquote&gt;

&lt;p&gt;In this way we can parse the output of &lt;code&gt;lsof&lt;/code&gt; and get the names and process IDs of any process that has a given file path open.&lt;/p&gt;

&lt;h4&gt;Running with elevated privileges&lt;/h4&gt;

&lt;p&gt;For killing tasks, I wanted to run with administrator privileges, so that any process could be killed.&lt;/p&gt;

&lt;p&gt;To make the design as consistent as possible, I created a method that would invoke a process with different privileges that looked as much like the &lt;code&gt;NSTask&lt;/code&gt; method as possible:&lt;/p&gt;

&lt;pre&gt;+ (NSString *)stringByLaunchingPath:(NSString *)processPath
    withArguments:(NSArray *)arguments
    authorization:(SFAuthorization *)authorization
    error:(NSError **)error&lt;/pre&gt;

&lt;p&gt;This method then works the same as the previous method except it requires an &lt;code&gt;SFAuthorization&lt;/code&gt; object and it will not return standard error in the &lt;code&gt;NSError&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;Creating the authorization object is quite simple:&lt;/p&gt;

&lt;pre&gt;authorization = [SFAuthorization authorization];
BOOL result =
    [authorization
        obtainWithRights:NULL
        flags:kAuthorizationFlagExtendRights
        environment:NULL
        authorizedRights:NULL
if (!result)
{
    NSLog(@"SFAuthorization error: %@", [error localizedDescription]); 
    return;
}&lt;/pre&gt;

&lt;p&gt;This is an authorization object for launching another process with administrator rights (&lt;code&gt;kAuthorizationFlagExtendRights&lt;/code&gt;) and no other options set. When used, this will prompt the user for an administrator password.&lt;/p&gt;

&lt;p&gt;Running the administrator rights process is then handled with:&lt;/p&gt;

&lt;pre&gt;OSErr processError =
    AuthorizationExecuteWithPrivileges(
        [authorization authorizationRef],
        [processPath UTF8String],
        kAuthorizationFlagDefaults,
        (char *const *)argv,
        &amp;processOutput);&lt;/pre&gt;

&lt;p&gt;The C-style &lt;code&gt;argv&lt;/code&gt; array is a bit annoying to create from an Objective-C &lt;code&gt;NSArray&lt;/code&gt; of &lt;code&gt;NSStrings&lt;/code&gt; and using &lt;code&gt;fread&lt;/code&gt; to read the output from &lt;code&gt;processOutput&lt;/code&gt; is also a pain but once the input and output data wrangling is done, this can work as simply as the &lt;code&gt;NSTask&lt;/code&gt;-based invocation.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Warning:&lt;/strong&gt; running with elevated privileges is &lt;em&gt;dangerous&lt;/em&gt;. Don't do this casually in your code, think about it first. And as a user of programs, don't enter your administrator password unless you trust the program you're running (be careful of potential malware and trojans).&lt;/blockquote&gt;

&lt;h4&gt;Other things that make an application&lt;/h4&gt;

&lt;p&gt;The application in this week's post contains a number of features that aren't relevant to this post but are interesting and useful nevertheless. These include:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Drag and drop of files onto the view&lt;/strong&gt; using &lt;code&gt;draggingEntered:&lt;/code&gt;, &lt;code&gt;draggingExited:&lt;/code&gt; and &lt;code&gt;performDragOperation:&lt;/code&gt; to handle the drag and drawing a highlighting rect to indicate drag focus using &lt;code&gt;NSSetFocusRingStyle&lt;/code&gt; and &lt;code&gt;bezierPathWithRect:&lt;/code&gt;. See the &lt;code&gt;FileDragReceivingView&lt;/code&gt; that I've set as the &lt;code&gt;contentView&lt;/code&gt; of the window.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opening files from the Finder/Dock without NSDocument&lt;/strong&gt; using the &lt;code&gt;NSApplication&lt;/code&gt; delegate method &lt;code&gt;application:openFiles:&lt;/code&gt; and an "any" &lt;code&gt;DocumentType&lt;/code&gt; listed in the &lt;code&gt;Info.plist&lt;/code&gt; file.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;And oh, how I miss &lt;code&gt;NSArrayController&lt;/code&gt; and bindings on &lt;code&gt;NSTableView&lt;/code&gt; when I'm working on the iPhone. They make populating a table of results so much easier.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the complete &lt;a href="http://cocoawithlove.googlepages.com/OpenFileKiller.zip"&gt;Open File Killer project&lt;/a&gt; (70kB).&lt;/blockquote&gt;

&lt;p&gt;The default process-launching and string-handling in Cocoa are not heavily geared towards command-line shell style invocation and handling but it doesn't take much to create a few wrapper methods that will make this a lot easier.&lt;/p&gt;

&lt;p&gt;Mac OS X has lots of standard in/out based executables: POSIX, BSD, Mac OS X Admin Tools, Developer Tools and any number of open source tools that you might load through package managers or other means. That's a lot of functionality available to your program and, when done right, using these tools should be as simple as invoking a method on a class.&lt;/p&gt;

&lt;p&gt;The sample application shows this in action. The code in &lt;code&gt;KillerController&lt;/code&gt; is more verbose than an equivalent application in a scripting language might be but verbose compared to another language does not equal worse. The Objective-C code is not significantly more complex than a typical scripting language performing the same tasks (the verbosity is mostly word and operator length plus formatting, not extra operators and commands), yet it is fast, handles errors gracefully and integrates smoothly into the user-interface.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-5472158567100919144?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/5472158567100919144/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=5472158567100919144" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5472158567100919144?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5472158567100919144?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/05/invoking-other-processes-in-cocoa.html" title="Invoking other processes in Cocoa" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Dk4HRHk_fCp7ImA9WxJRFE4.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1450729400577306994</id><published>2009-04-28T00:09:00.001-07:00</published><updated>2009-05-15T17:48:55.744-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-15T17:48:55.744-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><category scheme="http://www.blogger.com/atom/ns#" term="UIKit" /><title>Easy custom UITableView drawing</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;It is really easy to customize your &lt;code&gt;UITableView&lt;/code&gt;s. I'll show you how to completely customize the appearance of &lt;code&gt;UITableView&lt;/code&gt;s without overriding or subclassing and without the need for any tricky hackery.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Make my table pretty&lt;/h4&gt;

&lt;p&gt;The core of most iPhone applications is the &lt;code&gt;UITableView&lt;/code&gt;. To make your iPhone application stand out, the simplest way is to make your &lt;code&gt;UITableView&lt;/code&gt; look good.&lt;/p&gt;

&lt;p&gt;Customizing your &lt;code&gt;UITableView&lt;/code&gt; can be really easy. You don't need custom drawing code. You don't need subclasses of anything. Cocoa Touch provides all the drawing capability you need, all you have to do is use the right classes in the right ways and provide the layout.&lt;/p&gt;

&lt;h4&gt;The sample application&lt;/h4&gt;

&lt;p&gt;The approach I'll show you will turn the table on the left into the table on the right:&lt;/p&gt;

&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/SfW4y9Ic6SI/AAAAAAAAASw/LXvmLTvjCQU/customtableview.png?imgmax=800" alt="customtableview.png" border="0" width="550" height="405" /&gt;

&lt;p style="text-align:center;"&gt;&lt;em&gt;Left: a default &lt;code&gt;UITableView&lt;/code&gt; with three rows. Right: the same table view after customization.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;How to fail at UITableView customizing&lt;/h4&gt;

&lt;p&gt;Coming from Mac OS X made it harder for me &amp;mdash; &lt;code&gt;UITableView&lt;/code&gt; needs to be customized in a very particular way and structurally, it is very different to Mac OS X's &lt;code&gt;NSTableView&lt;/code&gt; and &lt;code&gt;NSCell&lt;/code&gt; drawing.&lt;/p&gt;

&lt;p&gt;The following are all &lt;em&gt;&lt;strong&gt;really bad ways&lt;/strong&gt;&lt;/em&gt; to customize a table (even though you can make it work):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subclassing &lt;code&gt;UITableView&lt;/code&gt; to customize drawing&lt;/li&gt;
&lt;li&gt;Subclassing &lt;code&gt;UITableViewCell&lt;/code&gt; to customize drawing&lt;/li&gt;
&lt;li&gt;Creating your own array of &lt;code&gt;UITableViewCell&lt;/code&gt;s and returning these instead of using &lt;code&gt;dequeueReusableCellWithIdentifier:&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point is only peripherally related to drawing but it will significantly slow your drawing down. Don't do it.&lt;/p&gt;

&lt;p&gt;If you have ever done any of these things, you're making it hard on yourself.&lt;/p&gt;

&lt;h4&gt;How to succeed at UITableView customizing&lt;/h4&gt;

&lt;p&gt;There are only a few points to understand related to table drawing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;: the &lt;code&gt;UITableView&lt;/code&gt; does not itself draw anything except the background. To customize the background of a &lt;code&gt;UITableView&lt;/code&gt;, all you need to do is set its &lt;code&gt;backgroundColor&lt;/code&gt; to &lt;code&gt;[UIColor clearColor]&lt;/code&gt; and you can draw your own background in a view &lt;em&gt;behind&lt;/em&gt; the &lt;code&gt;UITableView&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;: The &lt;code&gt;tableHeaderView&lt;/code&gt; (and the table footer and section headers and footers) need not be just a title. You can insert your own view, with its own subviews in the table header, giving layout and custom drawing freedom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third&lt;/strong&gt;: &lt;code&gt;UITableViewCell&lt;/code&gt; is composed of 5 different subviews. Customizing the right subview is the secret to good &lt;code&gt;UITableViewCell&lt;/code&gt; drawing. The subviews are:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;code&gt;backgroundView&lt;/code&gt; &amp;mdash; the entire background of the row (including what looks like the &lt;code&gt;UITableView&lt;/code&gt;'s background in &lt;code&gt;UITableViewStyleGrouped&lt;/code&gt; style tables.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;selectedBackgroundView&lt;/code&gt; &amp;mdash; replaces the &lt;code&gt;backgroundView&lt;/code&gt; when the row is selected.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;image&lt;/code&gt; &amp;mdash; a customizable image (not actually a subview) at the left of the cell.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;accessoryView&lt;/code&gt; &amp;mdash; a customizable view at the right of the cell.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contentView&lt;/code&gt; &amp;mdash; a customizable view between the &lt;code&gt;image&lt;/code&gt; and the &lt;code&gt;accessoryView&lt;/code&gt; (technically, it extends behind the &lt;code&gt;image&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can customize any of these (except &lt;code&gt;image&lt;/code&gt; which must be a &lt;code&gt;UIImage&lt;/code&gt;) using your own custom drawn views.&lt;/p&gt;

&lt;p&gt;However, since the pixel size of the table never changes, it is often easiest just to use &lt;code&gt;UIImageView&lt;/code&gt;s for each of them. Then you can take highly complex views drawn in separate programs, cut them into the 5 necessary pieces and let the automatic caching of &lt;code&gt;UIImage&lt;/code&gt;'s named image cache manage your memory for you.&lt;/p&gt;

&lt;p&gt;There is an argument against drawing your views in code and that is that the iPhone's drawing is not nearly as fast as Mac OS X. Operations like gradients and multiple overlapped components can really tax the iPhone.&lt;/p&gt;

&lt;p&gt;Custom drawing code is a good choice for simple and flat colour drawing. In most other cases &amp;mdash; as in this post &amp;mdash; I recommend you use &lt;code&gt;UIImageView&lt;/code&gt; to draw your views in a table.&lt;/p&gt;

&lt;h4&gt;Implementation&lt;/h4&gt;

&lt;p&gt;With all custom drawing handled by &lt;code&gt;UIImageView&lt;/code&gt;, that still leaves some work to do. You must handle all layout and configuring of views.&lt;/p&gt;

&lt;h5&gt;Configuration of the UITableView and layout of the table header&lt;/h5&gt;

&lt;p&gt;As an example of what that means, have a look at the &lt;code&gt;viewDidLoad&lt;/code&gt; method for this post:&lt;/p&gt;

&lt;pre&gt;- (void)viewDidLoad
{
    //
    // Change the properties of the imageView and tableView (these could be set
    // in interface builder instead).
    //
    tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    tableView.rowHeight = 100;
    tableView.backgroundColor = [UIColor clearColor];
    imageView.image = [UIImage imageNamed:@"gradientBackground.png"];
    
    //
    // Create a header view. Wrap it in a container to allow us to position
    // it better.
    //
    UIView *containerView =
        [[[UIView alloc]
            initWithFrame:CGRectMake(0, 0, 300, 60)]
        autorelease];
    UILabel *headerLabel =
        [[[UILabel alloc]
            initWithFrame:CGRectMake(10, 20, 300, 40)]
        autorelease];
    headerLabel.text = NSLocalizedString(@"Header for the table", @"");
    headerLabel.textColor = [UIColor whiteColor];
    headerLabel.shadowColor = [UIColor blackColor];
    headerLabel.shadowOffset = CGSizeMake(0, 1);
    headerLabel.font = [UIFont boldSystemFontOfSize:22];
    headerLabel.backgroundColor = [UIColor clearColor];
    [containerView addSubview:headerLabel];
    self.tableView.tableHeaderView = containerView;
}&lt;/pre&gt;

&lt;p&gt;This method handles the configuration of the &lt;code&gt;tableView&lt;/code&gt; (setting the &lt;code&gt;backgroundColor&lt;/code&gt;, &lt;code&gt;rowHeight&lt;/code&gt; and sets an image behind the table) but also creates its own layout for the table header.&lt;/p&gt;

&lt;p&gt;The layout of the header here is for the table's header view. You can include a custom header for every table section by implementing the &lt;code&gt;UITableViewDelegate&lt;/code&gt; method &lt;code&gt;tableView:viewForHeaderInSection:&lt;/code&gt;. There are equivalent properties and methods for the table and section footers.&lt;/p&gt;

&lt;p&gt;It is possible to handle this type of layout in Interface Builder and load the XIB files for this type of layout. Sadly though, on the iPhone, reading loading lots of views from XIB files is slow (I suspect this is due to slow reading from the Flash memory) and doesn't always allow configuration of every property.&lt;/p&gt;

&lt;p&gt;For this reason, I normally sketch my views in Interface Builder and then manually recreate the same thing in code. That's what I've done here: picking coordinates for the &lt;code&gt;headerLabel&lt;/code&gt; that looks balanced in the view.&lt;/p&gt;

&lt;h5&gt;Cell backgrounds&lt;/h5&gt;

&lt;p&gt;The cell background needs to incorporate the tops and bottoms of table "sections". For this reason, the &lt;code&gt;backgroundView&lt;/code&gt; and &lt;code&gt;selectedBackgroundView&lt;/code&gt; normally need to be set on a row-by-row basis.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;tableView:cellForRowAtIndexPath:&lt;/code&gt; method where you are configuring the cell for a given row, this code will handle that behavior:&lt;/p&gt;

&lt;pre&gt;UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [aTableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 &amp;&amp; row == sectionRows - 1)
{
    rowBackground = [UIImage imageNamed:@"topAndBottomRow.png"];
    selectionBackground = [UIImage imageNamed:@"topAndBottomRowSelected.png"];
}
else if (row == 0)
{
    rowBackground = [UIImage imageNamed:@"topRow.png"];
    selectionBackground = [UIImage imageNamed:@"topRowSelected.png"];
}
else if (row == sectionRows - 1)
{
    rowBackground = [UIImage imageNamed:@"bottomRow.png"];
    selectionBackground = [UIImage imageNamed:@"bottomRowSelected.png"];
}
else
{
    rowBackground = [UIImage imageNamed:@"middleRow.png"];
    selectionBackground = [UIImage imageNamed:@"middleRowSelected.png"];
}
((UIImageView *)cell.backgroundView).image = rowBackground;
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;&lt;/pre&gt;

&lt;h5&gt;Layout within the contentView&lt;/h5&gt;

&lt;p&gt;Layout of elements within the &lt;code&gt;contentView&lt;/code&gt; need only be set on construction of the &lt;code&gt;contentView&lt;/code&gt; (not on a row-by-row basis).&lt;/p&gt;

&lt;p&gt;Sadly, laying out &lt;code&gt;UILabel&lt;/code&gt;s in the &lt;code&gt;contentView&lt;/code&gt; (like the "Cell at row X." and "Some other infomation." lables in this example) is a little verbose.&lt;/p&gt;

&lt;p&gt;The following code is run immediately after the allocation of the &lt;code&gt;UITableViewCell&lt;/code&gt; to position the "Cell at row X." label:&lt;/p&gt;

&lt;pre&gt;const CGFloat LABEL_HEIGHT = 20;
UIImage *image = [UIImage imageNamed:@"imageA.png"];

//
// Create the label for the top row of text
//
topLabel =
    [[[UILabel alloc]
        initWithFrame:
            CGRectMake(
                image.size.width + 2.0 * cell.indentationWidth,
                0.5 * (aTableView.rowHeight - 2 * LABEL_HEIGHT),
                aTableView.bounds.size.width -
                    image.size.width - 4.0 * cell.indentationWidth
                        - indicatorImage.size.width,
                LABEL_HEIGHT)]
    autorelease];
[cell.contentView addSubview:topLabel];

//
// Configure the properties for the text that are the same on every row
//
topLabel.tag = TOP_LABEL_TAG;
topLabel.backgroundColor = [UIColor clearColor];
topLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];

//
// Create a background image view.
//
cell.backgroundView = [[[UIImageView alloc] init] autorelease];
cell.selectedBackgroundView = [[[UIImageView alloc] init] autorelease];&lt;/pre&gt;

&lt;p&gt;In my mind, it seems like there should be a more efficient way to do this. I hold out the possibility that there is.&lt;/p&gt;

&lt;p&gt;This code spends most of its time working out where the label should be placed. It needs to go right of the image, left of the &lt;code&gt;accessoryView&lt;/code&gt;, middle of the row but above the "Some other information." label.&lt;/p&gt;

&lt;h5&gt;Other adornments&lt;/h5&gt;

&lt;p&gt;The &lt;code&gt;accessoryView&lt;/code&gt; is just a &lt;code&gt;UIImageView&lt;/code&gt;. The &lt;code&gt;cell.image&lt;/code&gt; is set as a property. These are extremely simple additions but they make the table cells far more impactful.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the &lt;a href="http://cocoawithlove.googlepages.com/EasyCustomTable.zip"&gt;EasyCustomTable project as a zip file&lt;/a&gt; (60kb).&lt;/blockquote&gt;

&lt;p&gt;The code includes a &lt;code&gt;#define&lt;/code&gt; at the top that allows you to toggle the custom drawing on and off.&lt;/p&gt;

&lt;p&gt;None of this is particularly revolutionary (it is all in the iPhone documentation) but it is still easy to miss the properties and methods that make it easy.&lt;/p&gt;

&lt;p&gt;This does require custom images. If you've never drawn anything, now is a good time to learn &lt;a href="http://www.inkscape.org/"&gt;inkscape&lt;/a&gt; (it's free and very good for the price). You could also use Adobe Illustrator but if you have that much money, pay an artist to draw it for you.&lt;/p&gt;

&lt;p&gt;Layout of the content in code is probably the weakest part of the approach I've presented. To make it easier, you can pre-layout everything in Interface Builder and copy the layout into code. For complicated layouts, you could even try using &lt;a href="http://github.com/akosma/nib2objc/tree/master"&gt;nib2objc&lt;/a&gt; to convert your XIB files to code automatically (although I've never done this, I'm just mentioning nib2objc because the idea is so cool).&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1450729400577306994?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/1450729400577306994/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=1450729400577306994" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1450729400577306994?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1450729400577306994?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html" title="Easy custom UITableView drawing" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0cCRnozeip7ImA9WxJTEk8.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1347831429349393128</id><published>2009-04-18T21:13:00.001-07:00</published><updated>2009-04-20T02:51:07.482-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-20T02:51:07.482-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Objective-C" /><title>What does it mean when you assign [super init] to self?</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;One of the strangest pieces of common syntax in Objective-C is the line &lt;code&gt;self = [super init];&lt;/code&gt;. Without any explanation, this arrangement raises a few questions. Does this line set the &lt;code&gt;self&lt;/code&gt; value for the instance? Is &lt;code&gt;self&lt;/code&gt; just a variable like any other? If so, why have it at all? I'll address each of these questions and show how the compiler converts uses of &lt;code&gt;self&lt;/code&gt; and method invocations.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Converting a method invocation&lt;/h4&gt;
&lt;p&gt;The first step to understanding the &lt;code&gt;self&lt;/code&gt; parameter is to look at how the compiler converts a standard method invocation.&lt;/p&gt;

&lt;p&gt;When you type the following:&lt;/p&gt;

&lt;pre&gt;MyClass *myObject = [[MyClass alloc] initWithString:@"someString"];&lt;/pre&gt;

&lt;p&gt;The compiler converts this into function calls that look like this:&lt;/p&gt;

&lt;pre&gt;class myClass = objc_getClass("MyClass");
SEL allocSelector = @selector(alloc);
MyClass *myObject1 = objc_msgSend(myClass, allocSelector);

SEL initSelector = @selector(initWithString:);
MyClass *myObject2 = objc_msgSend(myObject1, initSelector, @"someString");&lt;/pre&gt;

&lt;p&gt;The compiler has slightly more efficient means of getting the &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;SEL&lt;/code&gt; values but if you look at assembly code, you will see &lt;code&gt;objc_msgSend&lt;/code&gt; calls for every method invocation.&lt;/p&gt;

&lt;h4&gt;So what is "self"?&lt;/h4&gt;

&lt;p&gt;Every method that you declare has two hidden parameters: &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;_cmd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following method:&lt;/p&gt;

&lt;pre&gt;- (id)initWithString:(NSString *)aString;&lt;/pre&gt;

&lt;p&gt;is converted by the compiler to the following function call:&lt;/p&gt;

&lt;pre&gt;id initWithString(id self, SEL _cmd, NSString *aString);&lt;/pre&gt;

&lt;p&gt;The reality is that &lt;code&gt;self&lt;/code&gt; is simply a hidden parameter on every method. Like any other parameter, it receives its value from the function invocation.&lt;/p&gt;

&lt;p&gt;Yes, &lt;code&gt;_cmd&lt;/code&gt; is also a hidden parameter on every method that you can access if you choose. In reality, there are few uses for the &lt;code&gt;_cmd&lt;/code&gt; parameter except in &lt;a href="http://cocoawithlove.com/2008/03/supersequent-implementation.html"&gt;obscure cases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can experiment with this by eliminating &lt;code&gt;objc_msgSend&lt;/code&gt; and invoking the function for a method directly. Instead of calling:&lt;/p&gt;

&lt;pre&gt;[myObject someMethodWithParameter:someValue];&lt;/pre&gt;

&lt;p&gt;You can reach your method implementation directly by recreating the work done by &lt;code&gt;objc_msgSend&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;SEL methodSelector = @selector(someMethodWithParameter:);
IMP someMethodFunction = class_getMethodImplementation([myObject class], methodSelector);
someMethodFunction(myObject, methodSelector, someValue);&lt;/pre&gt;

&lt;p&gt;The only reason why &lt;code&gt;self&lt;/code&gt; has a value on the inside of the &lt;code&gt;someMethodWithParameter:&lt;/code&gt; implementation is because the pointer &lt;code&gt;myObject&lt;/code&gt; is passed as the first parameter into &lt;code&gt;someMethodFunction&lt;/code&gt;. If you pass a different value as this first parameter, then &lt;code&gt;self&lt;/code&gt; will have a different value on the inside of the method.&lt;/p&gt;

&lt;p&gt;If you pass a value of a different class, you have a good chance of crashing the program. The following section explains why.&lt;/p&gt;

&lt;h4&gt;Why have a "self" parameter at all?&lt;/h4&gt;

&lt;p&gt;A method needs to know what data to act upon. The &lt;code&gt;self&lt;/code&gt; parameter tells the class the data to act upon and so is essential to object oriented programming.&lt;/p&gt;

&lt;p&gt;This statement may seem a little strange, since you can easily implement a method without using the &lt;code&gt;self&lt;/code&gt; parameter by name. The reality is that the compiler uses the &lt;code&gt;self&lt;/code&gt; parameter to resolve any reference to an instance variable inside a method.&lt;/p&gt;

&lt;p&gt;If you had a class defined like this:&lt;/p&gt;

&lt;pre&gt;@interface MyClass : NSObject
{
    NSInteger value;
}
- (void)setValueToZero;
@end&lt;/pre&gt;

&lt;p&gt;then the method:&lt;/p&gt;

&lt;pre&gt;- (void)setValueToZero
{
    value = 0;
}&lt;/pre&gt;

&lt;p&gt;is converted by the compiler into:&lt;/p&gt;

&lt;pre&gt;void setValueToZero(id self, SEL _cmd)
{
    self-&gt;value = 0;
}
&lt;/pre&gt;

&lt;p&gt;So &lt;code&gt;self&lt;/code&gt; is essential for accessing any instance variables, even if you never literally type "&lt;code&gt;self&lt;/code&gt;".&lt;/p&gt;

&lt;h4&gt;So does self already have a value when init is called?&lt;/h4&gt;

&lt;p&gt;If you remember back at the start, I said that the &lt;code&gt;initWithString:&lt;/code&gt; part of a typical &lt;code&gt;[[MyClass alloc] initWithString:@"someString"]&lt;/code&gt; invocation is converted into an &lt;code&gt;objc_msgSend&lt;/code&gt; call:&lt;/p&gt;

&lt;pre&gt;MyClass *myObject2 = objc_msgSend(myObject1, initSelector, @"someString");&lt;/pre&gt;

&lt;p&gt;So by the time we get to the inside of the method, &lt;code&gt;self&lt;/code&gt; already has a value; its value is &lt;code&gt;myObject1&lt;/code&gt; (i.e. the allocated object, as returned from the &lt;code&gt;[MyClass alloc]&lt;/code&gt; call. This is essential because without it, the &lt;code&gt;super&lt;/code&gt; invocation wouldn't be possible &amp;mdash; the &lt;code&gt;self&lt;/code&gt; value is used by the compiler to send the invocation:&lt;/p&gt;

&lt;pre&gt;[super init];&lt;/pre&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;pre&gt;objc_msgSendSuper(self, @selector(init));&lt;/pre&gt;

&lt;p&gt;Yes, &lt;code&gt;self&lt;/code&gt; already has a value when your initializer starts. In fact, it is almost guaranteed to be the correct, final value.&lt;/p&gt;

&lt;h4&gt;So why assign the value returned from [super init] to self?&lt;/h4&gt;

&lt;p&gt;Looking at a typical initializer method:&lt;/p&gt;

&lt;pre&gt;- (id)initWithString:(NSString *)aString
{
    self = [super init];
    if (self)
    {
        instanceString = [aString retain];
    }
    return self;
}&lt;/pre&gt;

&lt;p&gt;Why do we assign &lt;code&gt;[super init]&lt;/code&gt; to self here?&lt;/p&gt;

&lt;p&gt;The textbook reason is because &lt;code&gt;[super init]&lt;/code&gt; is permitted to do one of three things:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Return its own receiver (the &lt;code&gt;self&lt;/code&gt; pointer doesn't change) with inherited instance values initialized.&lt;/li&gt;
&lt;li&gt;Return a different object with inherited instance values initialized.&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;nil&lt;/code&gt;, indicating failure.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;In the first case, the assignment has no effect on &lt;code&gt;self&lt;/code&gt; and the &lt;code&gt;instanceString&lt;/code&gt; is set on in the original object (the line &lt;code&gt;instanceString = [aString retain];&lt;/code&gt; could have been the first line of the method and the result would be the same).&lt;/p&gt;

&lt;p&gt;In the third case, the initialization has failed. &lt;code&gt;self&lt;/code&gt; is set to &lt;code&gt;nil&lt;/code&gt;, no further action is taken and &lt;code&gt;nil&lt;/code&gt; is returned.&lt;/p&gt;

&lt;p&gt;The rationale for assigning to &lt;code&gt;self&lt;/code&gt; is associated with the second case: if the returned object is different, we want the:
&lt;pre&gt;        instanceString = [aString retain];&lt;/pre&gt;

&lt;p&gt;which gets converted to&lt;/p&gt;

&lt;pre&gt;        self-&gt;instanceString = [aString retain];&lt;/pre&gt;

&lt;p&gt;to act on the correct value, so we have to change the value of &lt;code&gt;self&lt;/code&gt; to point to this new object.&lt;/p&gt;

&lt;h4&gt;It's almost never required to initialize self&lt;/h4&gt;

&lt;p&gt;So the rationale for assigning to &lt;code&gt;self&lt;/code&gt; is that the &lt;code&gt;[super init]&lt;/code&gt; could return a different object and should initialize that different object instead of the old (likely invalid) object.&lt;/p&gt;

&lt;p&gt;The question to consider is then: when would &lt;code&gt;[super init]&lt;/code&gt; return a different object?&lt;/p&gt;

&lt;p&gt;The answer is that it will return different objects in one of the following situations:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Singleton object (always returns the singleton instead of any subsequent allocation)&lt;/li&gt;
&lt;li&gt;Other unique objects (&lt;code&gt;[NSNumber numberWithInteger:0]&lt;/code&gt; always returns the global "zero" object)&lt;/li&gt;
&lt;li&gt;Class clusters substitute private subclasses when you initialize an instance of the superclass.&lt;/li&gt;
&lt;li&gt;Classes which choose to reallocate the same (or compatible) class based on parameters passed into the initializer.&lt;/ul&gt;

&lt;p&gt;In all but the final case, continuing to initialize the returned object if it changes is a mistake &amp;mdash; the returned object is already completely initialized and isn't necessary related to your class anymore.&lt;/p&gt;

&lt;p&gt;So the list of three things that &lt;code&gt;[super init]&lt;/code&gt; is permitted to return can now be expanded to four by splitting the "Return a different object" point into two:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Return its own receiver (the &lt;code&gt;self&lt;/code&gt; pointer doesn't change) with inherited instance values initialized.&lt;/li&gt;
&lt;li&gt;Return an object of the same class, requiring further initialization.&lt;/li&gt;
&lt;li&gt;Return a different object that is already completely initialized.&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;nil&lt;/code&gt;, indicating failure.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;In this list, we now have two cases (2 and 3) which are incompatible. The typical "assign &lt;code&gt;[super init]&lt;/code&gt; to &lt;code&gt;self&lt;/code&gt;" initializer handles cases 1, 2 and 4.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;init&lt;/code&gt; approach to handle cases 1, 3 and 4 would actually be:&lt;/p&gt;

&lt;pre&gt;- (id)initWithString:(NSString *)aString
{
    id result = [super init];
    if (self == result)
    {
        instanceString = [aString retain];
    }
    return result;
}&lt;/pre&gt;

&lt;p&gt;So class clusters, singletons and unique objects all use case 3, putting dozens of Cocoa classes in this category. I'm only aware of &lt;code&gt;NSManagedObject&lt;/code&gt; that uses case 2. Curiously then, while case 3 is overwhelmingly more common, initializers that support 1, 2 and 4 but are incompatible with case 3 have become the standard. 

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;&lt;em&gt;Update&lt;/em&gt;: I have rewritten this conclusion to reflect the fact that I'm not actually suggesting you should stop using "assign &lt;code&gt;[super init]&lt;/code&gt; to &lt;code&gt;self&lt;/code&gt;" initializers. Thank you to everyone who invented creative ways to tell me I was wrong about this implication.&lt;/blockquote&gt; 

&lt;p&gt;You don't &lt;em&gt;need&lt;/em&gt; to assign &lt;code&gt;[super init]&lt;/code&gt; to &lt;code&gt;self&lt;/code&gt; to make most classes work. In some obscure cases, it is actually the wrong thing to do.&lt;/p&gt;

&lt;p&gt;So why do we continue to assign to &lt;code&gt;self&lt;/code&gt;? It's the traditional template for an initializer, and although it's wrong in some cases, it is right in other cases which have been written to expect this approach.&lt;/p&gt;

&lt;p&gt;Further to this is the consideration that class clusters and other classes likely to return unrelated or different, fully initialized objects from their init methods are not supposed to be subclassed in a normal way &amp;mdash; making code which favors them less relevant.&lt;/p&gt;

&lt;p&gt;The number of cases where &lt;code&gt;super&lt;/code&gt; returns an unrelated object are so small that they can easily be dealt with on a case-by-case basis &amp;mdash; a class will normally make it very clear when its initializers might return something other than the receiver or &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1347831429349393128?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/1347831429349393128/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=1347831429349393128" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1347831429349393128?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1347831429349393128?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html" title="What does it mean when you assign [super init] to self?" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkAFRH48cSp7ImA9WxJTFEo.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-2894826113190788186</id><published>2009-04-12T23:34:00.001-07:00</published><updated>2009-04-23T00:11:55.079-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-23T00:11:55.079-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><category scheme="http://www.blogger.com/atom/ns#" term="UIKit" /><category scheme="http://www.blogger.com/atom/ns#" term="CoreGraphics" /><title>Showing a "Loading..." message over the iPhone  keyboard</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;The "Text" (SMS) application on the iPhone uses a custom, semi-transparent view to show its "Sending..." message over the keyboard. I'll show you a simple class that can display semi-transparent loading messages and how you can display messages over the keyboard.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Introduction&lt;/h4&gt;
&lt;h5&gt;"Loading..." messages&lt;/h5&gt;
&lt;p&gt;When waiting for data loaded from the internet, many iPhone applications use a mostly black, semi-transparent view to block the display. Most use a basic "spinner" (&lt;code&gt;UIActivityIndicatorView&lt;/code&gt;) to reassure the user that the application is still running, frequently accompanied by "Loading..." text.&lt;/p&gt;

&lt;p&gt;Despite the prevalence of this type of loading message, it is not a standard control and must be constructed manually.&lt;/p&gt;

&lt;h5&gt;Finding the keyboard&lt;/h5&gt;

&lt;p&gt;Apple give no methods to locate the keyboard or even the current first responder in an iPhone application. I'll show you how you can find both.&lt;/p&gt;

&lt;h5&gt;The sample application&lt;/h5&gt;

&lt;p&gt;The sample LoadingView application in this post can display the following two types of loading window:&lt;/p&gt;

&lt;img src="http://lh3.ggpht.com/_gfktUGS0ov0/SeG2Fh4_kZI/AAAAAAAAASs/OifpF5FV5-8/loadingview.png?imgmax=800" alt="loadingview.png" border="0" width="529" height="384" /&gt;

&lt;p style="text-align:center;"&gt;&lt;em&gt;A full-window loading message and a keyboard-only loading message.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The sample application doesn't actually load anything. The "Refresh" button displays the full-window loading message for 5 seconds and the text field lets you enter some text and hit "Send" to see the keyboard-only loading message for 5 seconds.&lt;/p&gt;

&lt;h4&gt;Displaying a loading view&lt;/h4&gt;

&lt;p&gt;A loading view is not the most complicated piece of custom user-interface but there are a handful of common behaviors it should implement so it is a good idea to have a reusable class for the purpose.&lt;/p&gt;

&lt;p&gt;The behaviors in my loading view include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always fill the whole view that it blocks (even though it &lt;em&gt;looks&lt;/em&gt; inset on all sides for aesthetic reasons).&lt;/li&gt;
&lt;li&gt;Fade in and fade out when added and removed.&lt;/li&gt;
&lt;li&gt;Semi-transparent, allowing the unloaded view to show through.&lt;/li&gt;
&lt;li&gt;Autoresizeable so that a portrait to landscape rotation during loading won't disrupt the display.&lt;/li&gt;
&lt;li&gt;Displays a centered status message and activity indicator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To ensure that these behaviors are applied to the view on construction, I use a &lt;code&gt;loadingViewInView:&lt;/code&gt; method instead of a normal constructor. This method constructs, adds to superview and handles the fade animation all at once.&lt;/p&gt;

&lt;pre&gt;+ (id)loadingViewInView:(UIView *)aSuperview
{
    LoadingView *loadingView =
        [[[LoadingView alloc] initWithFrame:[aSuperview bounds]] autorelease];
    if (!loadingView)
    {
        return nil;
    }
    
    loadingView.opaque = NO;
    loadingView.autoresizingMask =
        UIViewAutoresizingFlexibleWidth |
        UIViewAutoresizingFlexibleHeight;
    [aSuperview addSubview:loadingView];

    // Code to create and configure the label and activity view goes here.
    // Download the sample project to see it.

    // Set up the fade-in animation
    CATransition *animation = [CATransition animation];
    [animation setType:kCATransitionFade];
    [[aSuperview layer] addAnimation:animation forKey:@"layerAnimation"];
    
    return loadingView;
}&lt;/pre&gt;

&lt;p&gt;All that's required to make it look semi-transparent is a custom drawing method.&lt;/p&gt;

&lt;pre&gt;- (void)drawRect:(CGRect)rect
{
    rect.size.height -= 1;
    rect.size.width -= 1;
    
    const CGFloat RECT_PADDING = 8.0;
    rect = CGRectInset(rect, RECT_PADDING, RECT_PADDING);
    
    const CGFloat ROUND_RECT_CORNER_RADIUS = 5.0;
    CGPathRef roundRectPath =
        NewPathWithRoundRect(rect, ROUND_RECT_CORNER_RADIUS);
    
    CGContextRef context = UIGraphicsGetCurrentContext();

    const CGFloat BACKGROUND_OPACITY = 0.85;
    CGContextSetRGBFillColor(context, 0, 0, 0, BACKGROUND_OPACITY);
    CGContextAddPath(context, roundRectPath);
    CGContextFillPath(context);

    const CGFloat STROKE_OPACITY = 0.25;
    CGContextSetRGBStrokeColor(context, 1, 1, 1, STROKE_OPACITY);
    CGContextAddPath(context, roundRectPath);
    CGContextStrokePath(context);

    CGPathRelease(roundRectPath);
}&lt;/pre&gt;

&lt;h4&gt;Round Rects are Everywhere!&lt;/h4&gt;

&lt;p&gt;I continue to find it strange that Apple don't provide a function to draw a round rectangle in one line. They do provide the (more flexible) &lt;code&gt;CGPathAddArcToPoint&lt;/code&gt; function but it lacks the simplicity of a single line function to handle the common case. Download the project and see how the implementation of &lt;code&gt;NewPathWithRoundRect&lt;/code&gt; creates round rects using the &lt;code&gt;CGPathAddArcToPoint&lt;/code&gt; function if you don't know how to draw round rects on the iPhone.&lt;/p&gt;

&lt;p&gt;The absence of a round rectangle function is particularly strange given the &lt;a href="http://www.folklore.org/StoryView.py?project=Macintosh&amp;story=Round_Rects_Are_Everywhere.txt&amp;sortOrder=Sort%20by%20Date&amp;detail=medium&amp;search=round%20rects"&gt;anecdote that Andy Hertzfeld relates on folklore.org&lt;/a&gt; and in his excellent book &lt;a href="http://oreilly.com/catalog/9780596007195/"&gt;Revolution in the Valley&lt;/a&gt;. In this anecdote, Steve Jobs drags Bill Atkinson on a walk around the block with Steve pointing out how everything is made of round rects until Bill relents and agrees to put the &lt;code&gt;RoundRect&lt;/code&gt; function into Quickdraw.&lt;/p&gt;

&lt;p&gt;Round rectangles continue to be everywhere on the iPhone &amp;mdash; maybe more so than on the Mac in 1984. It's a good idea to use a function like &lt;code&gt;NewPathWithRoundRect&lt;/code&gt; in your own code.&lt;/p&gt;

&lt;h4&gt;Finding the keyboard&lt;/h4&gt;

&lt;p&gt;The keyboard on the iPhone is an instance of &lt;code&gt;UIKeyboard&lt;/code&gt; (a private class) in its own &lt;code&gt;UIWindow&lt;/code&gt; (actually, it may share the window with the &lt;code&gt;UIAutoCorrectInlineView&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;You can find the &lt;code&gt;UIKeyboard&lt;/code&gt; with a simple search.&lt;/p&gt;

&lt;pre&gt;@implementation UIApplication (KeyboardView)

- (UIView *)keyboardView
{
    NSArray *windows = [self windows];
    for (UIWindow *window in [windows reverseObjectEnumerator])
    {
        for (UIView *view in [window subviews])
        {
            if (!strcmp(object_getClassName(view), "UIKeyboard"))
            {
                return view;
            }
        }
    }
    
    return nil;
}

@end&lt;/pre&gt;

&lt;p&gt;The keyboard itself is a series of nested views which eventually reach the underlying functionality for the keys:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;UIKeyboard&lt;/code&gt;&lt;/li&gt;
    &lt;ul&gt;&lt;li&gt;&lt;code&gt;UIKeyboardImpl&lt;/code&gt;&lt;/li&gt;
        &lt;ul&gt;&lt;li&gt;&lt;code&gt;UIKeyboardLayoutQWERTY&lt;/code&gt;&lt;/li&gt;
            &lt;ul&gt;&lt;li&gt;&lt;code&gt;UIKeyboardSublayout&lt;/code&gt;&lt;/li&gt;
                &lt;ul&gt;
&lt;li&gt;&lt;code&gt;UIImageView&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIKeyboardSpaceKeyView&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UIKeyboardReturnKeyView&lt;/code&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/ul&gt;
        &lt;/ul&gt;
    &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;Interestingly, the keys for the main part of the keyboard are all a single image. This arrangement probably explains why the "space" and "return" keys behave more like regular buttons than the other keys.&lt;/p&gt;

&lt;p&gt;For the sample application, since the implementation of &lt;code&gt;LoadingView&lt;/code&gt; will size the loading view to cover its immediate superview, passing the keyboard view fetched in this manner will create the keyboard-only loading view shown above.&lt;/p&gt;

&lt;p&gt;If you wanted to show a full-window &lt;code&gt;LoadingView&lt;/code&gt; that also covers the keyboard, you could pass the keyboard view's &lt;code&gt;superview&lt;/code&gt; to the &lt;code&gt;loadingViewInView:&lt;/code&gt; but you might want to add an extra 20 pixels padding at the top in this case, since the &lt;code&gt;superview&lt;/code&gt; (the window) extends underneath the status bar at the top of the window.&lt;/p&gt;

&lt;h4&gt;Finding the firstResponder&lt;/h4&gt;

&lt;p&gt;While it isn't required for the sample project, I thought I'd mention how to fetch a related piece of information: the &lt;code&gt;firstResponder&lt;/code&gt; in an iPhone application.&lt;/p&gt;

&lt;p&gt;On the iPhone &lt;code&gt;firstResponder&lt;/code&gt; is the view which has the current keyboard focus (or &lt;code&gt;nil&lt;/code&gt; if no view is focussed).&lt;/p&gt;

&lt;p&gt;This is an important piece of information, so it's strange that Apple didn't choose to provide a public method to access it. Curiously, there is a method, &lt;code&gt;firstResponder&lt;/code&gt;, on &lt;code&gt;UIWindow&lt;/code&gt; which returns this value but it isn't public. This will work:&lt;/p&gt;

&lt;pre&gt;UIView *firstResponder =
    [[UIApplication sharedApplication]
        keyWindow]
            performSelector:@selector(firstResponder)];&lt;/pre&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can see all this code and more in the sample project for this post: &lt;a href="http://cocoawithlove.googlepages.com/LoadingView.zip"&gt;LoadingView.zip&lt;/a&gt; (129kB)&lt;/blockquote&gt;

&lt;p&gt;Displaying a loading view is not a very difficult task (lots of people write their own) but implementing all of the different expected behaviors is time consuming &amp;mdash; the implementation in this post is at least 65 lines of code, depending on how you count it &amp;mdash; so keeping a resusable implementation can save a lot of time.&lt;/p&gt;

&lt;p&gt;Finding the keyboard and finding the current first responder on the iPhone are harder to work out since the API is hidden, and it requires a little investigative work.&lt;/p&gt;

&lt;p&gt;Putting it all together, you could easily recreate Apple's "Sending..." progress view used in the Text program.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-2894826113190788186?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/2894826113190788186/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=2894826113190788186" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/2894826113190788186?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/2894826113190788186?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/04/showing-message-over-iphone-keyboard.html" title="Showing a &amp;quot;Loading...&amp;quot; message over the iPhone  keyboard" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CU4MSH4_cCp7ImA9WxVaEUk.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-7162962397755796218</id><published>2009-04-05T18:42:00.001-07:00</published><updated>2009-04-07T15:39:49.048-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-07T15:39:49.048-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Objective-C" /><title>8 Confusing Objective-C Warnings and Errors</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Objective-C's unique syntax results in unique ways of making mistakes. In this post, I look at the compiler warnings and errors GCC outputs when you make mistakes or potential mistakes in your Objective-C syntax and show you how to fix them.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Every warning &lt;em&gt;is&lt;/em&gt; an error&lt;/h4&gt;

&lt;p&gt;Objective-C lets a lot of potentially fatal problems related to method invocations go through as warnings. This is because the method lookup system is dynamic and from the compiler's perspective you &lt;em&gt;could&lt;/em&gt; provide a resolution at runtime.&lt;/p&gt;

&lt;p&gt;To make this overly permissive situation in Objective-C safer, you should treat every warning as a potentially fatal error. This means that you should turn on &lt;code&gt;GCC_TREAT_WARNINGS_AS_ERRORS&lt;/code&gt; (&lt;code&gt;-Werror&lt;/code&gt;) in your build settings so you can catch these problems and fix them instead of letting your program run until it crashes at runtime.&lt;/p&gt;

&lt;p&gt;Every warning has an approach to eliminate the warning. These warning-less approaches invariably represent better design. I'll let you know how to fix each of the warnings/errors listed here.&lt;/p&gt;

&lt;h4&gt;1. Improperly nested method brackets&lt;/h4&gt;

&lt;pre&gt;/path/file.m:15: error: syntax error before 'autorelease'&lt;/pre&gt;

&lt;p&gt;(where &lt;code&gt;autorelease&lt;/code&gt; could be the first word in any method) or&lt;/p&gt;

&lt;pre&gt;/path/file.m:15: error: syntax error before ';' token&lt;/pre&gt;

&lt;p&gt;These are the only syntax errors I'm going to include in this list &amp;mdash; my reason for including them is that, despite the obvious nature of the problem and its high occurrence rate, GCC presents the errors in a non-descript way that doesn't reveal the underlying problem.&lt;/p&gt;

&lt;p&gt;The first error is "you are missing an opening bracket somewhere before this". The second error is "you are missing a closing bracket immediately before the semi-colon".&lt;/p&gt;

&lt;p&gt;It would be great if GCC gave an error like "unmatched bracket" and pointed to the unmatched bracket. Apple &lt;a href="http://clang.llvm.org/diagnostics.html"&gt;are hinting&lt;/a&gt; that future clang-based compilers may do this but for now, you get one of these terse errors.&lt;/p&gt;

&lt;h4&gt;2. Trying to use a forward class&lt;/h4&gt;

&lt;pre&gt;/path/file.m:22: warning: receiver 'Test' is a forward class and corresponding @interface may not exist&lt;/pre&gt;

&lt;p&gt;This is a simple error but many people (especially those accustomed to other languages that don't have separate declaration and implementation) find it confusing because they may not be certain what a "forward class" is.&lt;/p&gt;

&lt;p&gt;I'd like to take this opportunity to tell you: if you don't know what a &lt;a href="http://en.wikipedia.org/wiki/Forward_declaration"&gt;forward declaration&lt;/a&gt; is, or you've never used &lt;code&gt;@class&lt;/code&gt; before, you need to &lt;a href="http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html"&gt;read about it&lt;/a&gt;. In brief: a &lt;code&gt;@class&lt;/code&gt; forward declaration tells the compiler that a given name is a class but avoids the need to import the whole declaration (which would create an undesirable cross-dependency in the header file).&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Basic rule:&lt;/strong&gt; in &lt;em&gt;header&lt;/em&gt; files, never &lt;code&gt;#import&lt;/code&gt; another class from the same framework/application except the super class &amp;mdash; always use an &lt;code&gt;@class&lt;/code&gt; forward definition instead. The &lt;code&gt;#import&lt;/code&gt; for a class should always be in the &lt;em&gt;implementation&lt;/em&gt; (.m) file. Using &lt;code&gt;#import&lt;/code&gt; for other frameworks (like &lt;code&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;&lt;/code&gt;) is okay.&lt;/blockquote&gt;

&lt;p&gt;The cause of this warning is failure to follow the second part of this basic rule: you need to &lt;code&gt;#import&lt;/code&gt; the actual definition in your implementation file.&lt;/p&gt;

&lt;p&gt;Older versions of GCC (prior to 4.0) didn't always give this warning. The result was that you could accidentally use classes that didn't exist (resulting in runtime crashes). This warning is a big improvement.&lt;/p&gt;

&lt;h4&gt;3. Recursive headers&lt;/h4&gt;

&lt;pre&gt;/path/file.h:13: warning: duplicate interface declaration for class 'Test'
/path/file.h:15: error: redefinition of 'struct Test'&lt;/pre&gt;

&lt;p&gt;There are two ways to get this error. The first is mundane: you have declared two classes with the same name &amp;mdash; not an Objective-C specific problem.&lt;/p&gt;

&lt;p&gt;The second is that you have used &lt;code&gt;#include&lt;/code&gt; to import the header declaration instead of &lt;code&gt;#import&lt;/code&gt;. This is especially recognizable when you see the error dozens (or hundreds) of times in a row, especially if it is further accompanied by:&lt;/p&gt;

&lt;pre&gt;/path/file.h:9:35: error: #include nested too deeply&lt;/pre&gt;

&lt;p&gt;Objective-C expects that all header files are imported using &lt;code&gt;#import&lt;/code&gt; which prevents recursive inclusion, so files don't guard against repeat inclusion as they normally do in standard C.&lt;/p&gt;

&lt;p&gt;Solution: always use &lt;code&gt;#import&lt;/code&gt; to import header declarations (and don't listen to Richard Stallman's rants against the &lt;code&gt;#import&lt;/code&gt; keyword &amp;mdash; he is... different).&lt;/p&gt;

&lt;h4&gt;4. Interface not imported&lt;/h4&gt;

&lt;pre&gt;/path/file.m:26: warning: no '-blah' method found
/path/file.m:26: warning: (Messages without a matching method signature
/path/file.m:26: warning: will be assumed to return 'id' and accept
/path/file.m:26: warning: '...' as arguments.)&lt;/pre&gt;

&lt;p&gt;The mundane explanation is that there is no &lt;code&gt;blah&lt;/code&gt; method (you've simply mistyped it).&lt;/p&gt;

&lt;p&gt;However, Objective-C provides a few ways to get this error, even when the method &lt;em&gt;does&lt;/em&gt; exist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The class where &lt;code&gt;-blah&lt;/code&gt; is defined may not be in the set of imported classes. This can happen when the object you tried to invoke &lt;code&gt;-blah&lt;/code&gt; on is declared as an &lt;code&gt;id&lt;/code&gt; or the class is only forward declared.&lt;/li&gt;
&lt;li&gt;You have imported the base class but the method is declared on a &lt;code&gt;@category&lt;/code&gt;, which is not imported.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In either case, the solution is to find the header that defines the method and &lt;code&gt;#import&lt;/code&gt; it.&lt;/p&gt;

&lt;p&gt;There is one further situation where this error can occur: when there is no implementation of the method at compile-time at all. This can further be broken into two cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runtime handled methods with clear association with a particular class. For example: accessor methods for the attributes of a Core Data &lt;code&gt;NSManagedObject&lt;/code&gt;s. For methods like this, you should declare the method in a category (even though there will be no implementation at compile-time) and import this category.&lt;/li&gt;
&lt;li&gt;Runtime handled methods with no clear class association. To highlight the runtime and unusual situation involved in this situation you should use &lt;code&gt;[object performSelector:@selector(weirdRuntimeMethod)]&lt;/code&gt; instead of writing &lt;code&gt;[object weirdRuntimeMethod]&lt;/code&gt; and causing compiler warnings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;5. Multiple, incompatible methods&lt;/h4&gt;

&lt;pre&gt;/path/file.m:24: warning: multiple methods named '-setStringValue:' found&lt;/pre&gt;

&lt;p&gt;Normally, Objective-C won't complain if there are multiple methods matching a given name (it assumes runtime lookup will work it out) so this warning may be surprising when it occurs.&lt;/p&gt;

&lt;p&gt;This type of problem occurs when you have multiple declarations with the same method name but the arguments to the method are different sizes (e.g. one declaration expects a 32-bit long parameter and one declaration expects a 64-bit long parameter). This is important because parameter sizes are fixed at compile-time (runtime lookup can't change it).&lt;/p&gt;

&lt;p&gt;The solution is to tell the compiler which method is the correct method by casting your object to the exact class involved. For example:&lt;/p&gt;

&lt;pre&gt;[(NSXMLNode *)myObject setStringValue:@"value"];&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;NSXMLNode *myXMLNodeObject = myObject;
[myXMLNodeObject setStringValue:@"value"];&lt;/pre&gt;

&lt;p&gt;Both of these solutions produce the same compiled output.&lt;/p&gt;

&lt;h4&gt;6. Accessing a property on the wrong type&lt;/h4&gt;

&lt;pre&gt;/path/file.m:23: error: request for member 'value' in something not a structure or union&lt;/pre&gt;

&lt;p&gt;This error can occur in standard C code when using &lt;code&gt;struct&lt;/code&gt; or &lt;code&gt;union&lt;/code&gt; as the error reports.&lt;/p&gt;

&lt;p&gt;In Objective-C 2.0, it also occurs when accessing an Objective-C 2.0 property on a class and the compiler can't find the property.&lt;/p&gt;

&lt;p&gt;If this error occurs and you have typed the name correctly, you probably need to cast the object to the correct class. i.e. if &lt;code&gt;value&lt;/code&gt; is a property of &lt;code&gt;MyClass&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;id value = ((MyClass *)object).value;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;MyClass *myClassObject = object;
id value = myClassObject.value;&lt;/pre&gt;

&lt;p&gt;These solutions are, as before, both equivalent.&lt;/p&gt;

&lt;p&gt;The other potential cause of this error is that &lt;code&gt;MyClass&lt;/code&gt; is not imported correctly, so be certain to check this as well.&lt;/p&gt;

&lt;h4&gt;7. Implicit downcasting on assignment&lt;/h4&gt;

&lt;pre&gt;/path/file.m:22: warning: initialization from distinct Objective-C type&lt;/pre&gt;

&lt;p&gt;The mundane cause of this error is that you've tried to assign the return value of a method to an unrelated object type. That's just an error and you need to fix it.&lt;/p&gt;

&lt;p&gt;The trickier case is an implicit downcast. By this I mean: the method has returned a super class (like &lt;code&gt;NSObject&lt;/code&gt;) but you know it is actually a child class (like &lt;code&gt;MyClass&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In this situation you must explicitly cast:&lt;/p&gt;

&lt;pre&gt;MyClass *myClassObject = (MyClass *)[someObject getObject];&lt;/pre&gt;

&lt;p&gt;C++ has the &lt;code&gt;dynamic_cast&lt;/code&gt; operator for this type of action, which verifies that &lt;code&gt;myClassObject&lt;/code&gt; is correctly a &lt;code&gt;MyClass&lt;/code&gt; object. In Objective-C if you're concerned about runtime type, you should use:&lt;/p&gt;

&lt;pre&gt;NSAssert([myClassObject isKindOfClass:[MyClass class]],
    @"Return value is not of type MyClass as expected.");&lt;/pre&gt;

&lt;p&gt;You can use your own &lt;code&gt;AssertCast&lt;/code&gt; macro to make this operation easier if you do it a lot.&lt;/p&gt;

&lt;p&gt;There are two cases where implict casts are allowed:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;upcasts (i.e. &lt;code&gt;NSObject *myObject = myClassObject;&lt;/code&gt; is okay)&lt;/li&gt;
&lt;li&gt;implicit conversions from &lt;code&gt;id&lt;/code&gt; to anything (&lt;code&gt;id&lt;/code&gt; is the universal object and can be implicitly cast or used as anything)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;This error can also occur in the case where the assignment is actually an upcast but the source class has only a forward declaration &amp;mdash; so you may also need to import the declaration if it is not imported.&lt;/p&gt;

&lt;h4&gt;8. Implicit downcasting of parameters&lt;/h4&gt;

&lt;pre&gt;/path/file.m:24: warning: passing argument 1 of 'test:' from distinct Objective-C type&lt;/pre&gt;

&lt;p&gt;The causes and solutions for this are identical to downcasting on assignment. Cast correctly and import declarations as appropriate.&lt;/p&gt;

&lt;p&gt;I know, this warning seems like a duplicate of number 7 but it's a programming blog: I had to have 8 things. In my head, I've stored them all in an array indexed from 0 to 7.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;Never be content with warnings in your code. Always work to understand why GCC is issuing the warning and fix your code. Your code will be easier to understand and be safer at runtime.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-7162962397755796218?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/7162962397755796218/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=7162962397755796218" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/7162962397755796218?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/7162962397755796218?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/04/8-confusing-objective-c-warnings-and.html" title="8 Confusing Objective-C Warnings and Errors" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;AkAMRHk8fCp7ImA9WxVbE0o.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-8365036296656299859</id><published>2009-03-28T17:37:00.001-07:00</published><updated>2009-03-29T19:06:25.774-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-29T19:06:25.774-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><category scheme="http://www.blogger.com/atom/ns#" term="Standard C" /><title>Using NSKeyedArchiver to archive a C linked-list</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;&lt;code&gt;NSKeyedArchiver&lt;/code&gt; provides some support for archiving C primitive types but provides no support for pointers to C structs. I'll show you how you can archive a linked list of C structs, despite the lack of support in &lt;code&gt;NSKeyedArchiver&lt;/code&gt;.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Standard C&lt;/h4&gt;
&lt;p&gt;Cocoa contains very little support for standard C data structures. The reason for this is pretty simple: introspection. An Objective-C object can report on what it is, its block size, its ivars and methods. Protocols can be implemented to provide further metadata about the object. With a pointer to an arbitrary block of standard C data, you have no information at all about the type and structure of the block.&lt;/p&gt;

&lt;p&gt;While keeping all your data in Objective-C objects works well most of the time, sometimes you'll need to work with standard C data structures &amp;mdash; for example when working with data produced by third party libraries.&lt;/p&gt;

&lt;p&gt;To show how to use C data structures with libraries that expect Objective-C objects, I'll show you how to archive a linked-list of C structs using &lt;code&gt;NSKeyedArchiver&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;Metadata and wrappers&lt;/h4&gt;

&lt;p&gt;As I mentioned, the real problem with arbitrary C data is that it offers no introspection &amp;mdash; we must be able to ask our data about its metadata. Specifically, we will need to know the size of the list node structs (we can copy the whole struct as a block of data) and the offsets within the struct of pointers to other list nodes.&lt;/p&gt;

&lt;p&gt;In addition to metadata, we need a way to deal with pointers. &lt;code&gt;NSKeyedArchiver&lt;/code&gt; provides no way to encode an arbitrary pointer.&lt;/p&gt;

&lt;p&gt;To handle both these problems, the solution will use one Objective-C "wrapper" object to represent each struct, and one extra "context" object to encode data about the overall archive operation.&lt;/p&gt;

&lt;p&gt;The context object will encode the size of the struct and byte offsets of each pointer within the struct (since this data is stored once, not per object, we assume that every node in the linked list is the same type).&lt;/p&gt;

&lt;p&gt;The wrapper objects for each struct will serve two purposes: they will handle the encoding of each struct's data but they will also act as proxies for the pointers between structs &amp;mdash; allowing us to encode pointers to objects (permitted by &lt;code&gt;NSKeyedArchiver&lt;/code&gt;) instead of pointers to structs (not permitted).&lt;/p&gt;

&lt;p&gt;To allow the wrapper objects to act as proxies for each pointer, we will also need a dictionary that stores the mapping from struct to associated proxy object &amp;mdash; this mapping will be held in the context object.&lt;/p&gt;

&lt;h4&gt;Interface design&lt;/h4&gt;

&lt;pre&gt;@interface BlockWrapper : NSObject &amp;lt;NSCoding&amp;gt;
{
    BlockContext *blockContext;
    void *blockPointer;
}

@property (readonly) void *blockPointer;

- (id)initWithBlockContext:(BlockContext *)aBlockContext
    blockPointer:(void *)aBlockPointer;

@end&lt;/pre&gt;

&lt;p&gt;The data for the wrapper object is very simple: a &lt;code&gt;blockPointer&lt;/code&gt; that points to the data that the object will encode and &lt;code&gt;blockContext&lt;/code&gt; which points to the context object for the archive operation.&lt;/p&gt;

&lt;p&gt;I decided to name this class &lt;code&gt;BlockWrapper&lt;/code&gt; instead of &lt;code&gt;StructWrapper&lt;/code&gt; to properly reflect how the class handles the data it wraps &amp;mdash; as an arbitrary block of bytes.&lt;/p&gt;

&lt;pre&gt;@interface BlockContext : NSObject &amp;lt;NSCoding&amp;gt;
{
    CFMutableDictionaryRef blockToBlockWrapperMappings;
    void *startingBlock;
    size_t blockSize;
    NSArray *pointerOffsets;
}

@property (readonly) size_t blockSize;
@property (readonly) void *startingBlock;
@property (readonly, retain, nonatomic) NSArray *pointerOffsets;

- (id)initWithStartingBlock:(void *)aStartingBlock
    blockSize:(size_t)aBlockSize
    pointerOffsets:(NSArray *)aPointerOffsets;
- (BlockWrapper *)wrapperForBlock:(void *)aBlock;

@end&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;BlockContext&lt;/code&gt; class is fairly straightforward as well: it encodes all the previously discussed metadata about the block.&lt;/p&gt;

&lt;p&gt;Since I wanted this code to work for &lt;em&gt;any&lt;/em&gt; linked list node, I haven't hard-coded the number or location of pointers within each block &amp;mdash; I store the offsets of each pointer as an array.&lt;/p&gt; 

&lt;p&gt;The &lt;code&gt;wrapperForBlock:&lt;/code&gt; will be the correct way to find the &lt;code&gt;BlockWrapper&lt;/code&gt; object for any of our list node pointers. This method will return the corresponding &lt;code&gt;BlockWrapper&lt;/code&gt; from the &lt;code&gt;blockToBlockWrapperMappings&lt;/code&gt;, creating a new &lt;code&gt;BlockWrapper&lt;/code&gt; if one does not already exist for the given list node pointer.&lt;/p&gt;

&lt;p&gt;Notice that I use a &lt;code&gt;CFMutableDictionaryRef&lt;/code&gt; instead of an &lt;code&gt;NSDictionary&lt;/code&gt;. This is because the keys in this dictionary will be the pointers to the blocks, not Objective-C objects, and &lt;code&gt;NSDictionary&lt;/code&gt; requires that its keys be Objective-C objects. With &lt;code&gt;CFMutableDictionaryRef&lt;/code&gt;, we can configure the dictionary to handle raw pointers.&lt;/p&gt;

&lt;p&gt;Despite containing all this metadata during the encoding process, for its own encoding, the &lt;code&gt;BlockContext&lt;/code&gt; only needs to save the &lt;code&gt;startingBlock&lt;/code&gt; and &lt;code&gt;pointerOffsets&lt;/code&gt;. The &lt;code&gt;NSKeyedArchiver&lt;/code&gt; will implicitly store the &lt;code&gt;blockSize&lt;/code&gt; for each encoded block and the mappings from &lt;code&gt;BlockWrapper&lt;/code&gt; to pointer.&lt;/p&gt;

&lt;h4&gt;Encoding and decoding the BlockWrapper&lt;/h4&gt;

&lt;pre&gt;- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeBytes:blockPointer length:[blockContext blockSize] forKey:@"block"];
    [encoder encodeObject:blockContext forKey:@"blockContext"];

    NSMutableArray *blockWrapperArray =
        [NSMutableArray arrayWithCapacity:[[blockContext pointerOffsets] count]];

    for (NSNumber *offsetNumber in [blockContext pointerOffsets])
    {
        NSUInteger offset = [offsetNumber integerValue];
        void *childBlock = *(void **)((NSUInteger)blockPointer + offset);
        if (!childBlock)
        {
            [blockWrapperArray addObject:[NSNull null]];
            continue;
        }

        BlockWrapper *childWrapper = [blockContext wrapperForBlock:childBlock];
        [blockWrapperArray addObject:childWrapper];
    }
    
    [encoder encodeObject:blockWrapperArray forKey:@"childBlocks"];
}&lt;/pre&gt;

&lt;p&gt;Encoding the block itself and storing a pointer to the &lt;code&gt;BlockContext&lt;/code&gt; is simple. Most of the work in encoding relates to handling pointers to other nodes:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;get each pointer offset&lt;/li&gt;
&lt;li&gt;reading the value of the pointer from the block&lt;/li&gt;
&lt;li&gt;map the pointer's value to a &lt;code&gt;BlockWrapper&lt;/code&gt; object using the &lt;code&gt;blockContext&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;encoding each referenced &lt;code&gt;BlockWrapper&lt;/code&gt; in an &lt;code&gt;NSArray&lt;/code&gt; using the &lt;code&gt;childBlocks&lt;/code&gt; key&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Notice that &lt;code&gt;NULL&lt;/code&gt; pointers still require a &lt;code&gt;NSNull&lt;/code&gt; object in the &lt;code&gt;childBlocks&lt;/code&gt; array so that the indices in this array always correspond to the indices in the &lt;code&gt;pointerOffsets&lt;/code&gt; array.&lt;/p&gt;

&lt;p&gt;The decode process for &lt;code&gt;BlockWrapper&lt;/code&gt; is mostly the same work in reverse: decode the block, decode the reference to the context object and then set all of the pointers according to the decoded &lt;code&gt;childBlocks&lt;/code&gt; array.&lt;/p&gt;

&lt;pre&gt;- (id)initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if (self != nil)
    {
        NSUInteger blockSize;
        const void *bytes =
            [decoder decodeBytesForKey:@"block" returnedLength:&amp;blockSize];
        blockPointer = malloc(blockSize);
        memcpy(blockPointer, bytes, blockSize);
        
        BlockContext *context = [decoder decodeObjectForKey:@"blockContext"];

        NSArray *childBlocks = [decoder decodeObjectForKey:@"childBlocks"];
        NSArray *pointerOffsets = [context pointerOffsets];
        NSInteger i;
        NSInteger count = [childBlocks count];
        
        NSAssert(count == [pointerOffsets count],
            @"Mismatch between childBlocks and pointerOffsets");
        
        for (i = 0; i &amp;lt; count; i++)
        {
            BlockWrapper *wrapperObject = [childBlocks objectAtIndex:i];
            NSNumber *offsetNumber = [pointerOffsets objectAtIndex:i];
            NSUInteger offset = [offsetNumber integerValue];
            
            void *childPointer = 0;
            if (![wrapperObject isEqual:[NSNull null]])
            {
                childPointer = [wrapperObject blockPointer];
            }
            
            *(void **)((NSUInteger)blockPointer + offset) = childPointer;
        }
    }
    return self;
}&lt;/pre&gt;

&lt;p&gt;The biggest difference between decoding and encoding is that in decoding, we need to &lt;code&gt;malloc&lt;/code&gt; the memory for the list node (pointed to by &lt;code&gt;blockPointer&lt;/code&gt;). When encoding, this memory was allocated externally before we began.&lt;/p&gt;

&lt;p&gt;The result is that the code which unarchives the linked list is also responsible for &lt;code&gt;free&lt;/code&gt;-ing it.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;Download the complete solution (which includes a trivial sample program) &lt;a href="http://cocoawithlove.googlepages.com/LinkedListCoding.zip"&gt;LinkedListCoding.zip&lt;/a&gt; (48kB)&lt;/blockquote&gt;

&lt;p&gt;This solution will let you archive an arbitrary linked list of C structs using &lt;code&gt;NSKeyedArchiver&lt;/code&gt;. The solution does make some assumptions &amp;mdash; specifically, your list nodes must all be the same type and the only pointers must point to other list nodes or &lt;code&gt;NULL&lt;/code&gt;. Other list arrangements would require changes to the solution.&lt;/p&gt;

&lt;p&gt;Of course, this solution is not as elegant as avoiding linked lists altogether. If you have control over the code and it's simple enough, storing &lt;code&gt;NSObject&lt;/code&gt; in an &lt;code&gt;NSMutableArray&lt;/code&gt; is much better supported by Cocoa.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-8365036296656299859?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/8365036296656299859/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=8365036296656299859" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/8365036296656299859?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/8365036296656299859?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/03/using-nskeyedarchiver-to-archive-c.html" title="Using NSKeyedArchiver to archive a C linked-list" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEAMQ3kzfyp7ImA9WxVUF0Q.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-5523025999758641428</id><published>2009-03-22T19:33:00.001-07:00</published><updated>2009-03-23T00:19:42.787-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-23T00:19:42.787-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><category scheme="http://www.blogger.com/atom/ns#" term="UIKit" /><title>Recreating UITableViewController to increase code reuse</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;UITableViewController and UIViewController are the two most commonly implemented controllers on the iPhone. It may not always be clear what UITableViewController adds to its superclass. I'll show you what UITableViewController does by recreating its functionality on top of UIViewController and show you why doing this can provide a richer base controller class that you can use throughout your iPhone application.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;This week, an iPhone app&lt;/h4&gt;

&lt;p&gt;In this post, I'll present a small iPhone application that displays the time in a table on the front screen, with detail screens for each component when the respective row is clicked.&lt;/p&gt;

&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/ScYbVZLNsbI/AAAAAAAAASY/N2JOHgV3Q6Y/timeintable.png?imgmax=800" alt="timeintable.png" border="0" width="504" height="191" /&gt;

&lt;p style="text-align:center;"&gt;("second" shown on the right is the unit of time, not the 2nd row)&lt;/p&gt;

&lt;p&gt;With this application, the code to monitor the time and update when it changes is in a base class common to both the &lt;code&gt;UITableView&lt;/code&gt;'s controller (left) and the &lt;code&gt;UIView&lt;/code&gt;'s controller (right).&lt;/p&gt;

&lt;p&gt;If you followed the standard practice of using &lt;code&gt;UITableViewController&lt;/code&gt; subclasses for &lt;code&gt;UITableView&lt;/code&gt;-based screens and &lt;code&gt;UIViewController&lt;/code&gt; subclasses for all other screens, keeping this code common would not be possible. I'll show how to make it possible by recreating the functionality of &lt;code&gt;UITableViewController&lt;/code&gt; in your own &lt;code&gt;UIViewController&lt;/code&gt; subclasses.&lt;/p&gt;

&lt;h4&gt;UITableViewController versus UIViewController&lt;/h4&gt;
&lt;p&gt;Between &lt;code&gt;UITableView&lt;/code&gt; and navigation-based controllers, Apple did an excellent job of establishing a standard interaction paradigm for the iPhone. This established standard works so well that programmers use &lt;code&gt;UITableViewController&lt;/code&gt; for most screens in their programs.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;UITableViewController&lt;/code&gt; makes the simple, common case easier but it creates a problem if your program needs shared functionality between table view and views based on &lt;code&gt;UIViewController&lt;/code&gt; (where &lt;code&gt;self.view&lt;/code&gt; is not a &lt;code&gt;UITableView&lt;/code&gt;). The problem is that common functionality for screens in your program must now be duplicated &amp;mdash; once to include this functionality in your &lt;code&gt;UIViewController&lt;/code&gt; subclass and once to include the functionality in your &lt;code&gt;UITableViewController&lt;/code&gt; subclass.&lt;/p&gt;

&lt;p&gt;My preferred solution to this problem is to create my own program-wide base class which is a subclass of &lt;code&gt;UIViewController&lt;/code&gt;. I put my common code in the base class and when I need a controller for a &lt;code&gt;UITableView&lt;/code&gt;, recreate the work done by &lt;code&gt;UITableViewController&lt;/code&gt; in a subclass of my own base class which can then be the base class for all &lt;code&gt;UITableView&lt;/code&gt; controllers in my program.&lt;/p&gt;

&lt;h4&gt;Recreating UITableViewController&lt;/h4&gt;

&lt;p&gt;To recreate it, we need to know what &lt;code&gt;UITableViewController&lt;/code&gt; does. Given the class' ubiquity, it may be surprising to learn that it doesn't do very much.&lt;/p&gt;

&lt;p&gt;As detailed in the API documentation, &lt;code&gt;UITableViewController&lt;/code&gt; adds the following functionality:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;A constructor (&lt;code&gt;initWithStyle:&lt;/code&gt;) that sets the style for the default contructed table (if the table isn't constructed from a NIB file).&lt;/li&gt;
&lt;li&gt;An implementation of &lt;code&gt;loadView&lt;/code&gt; that creates the default table if the view controller is used without a NIB file.&lt;/li&gt;
&lt;li&gt;Implementation of the &lt;code&gt;tableView&lt;/code&gt; property.&lt;/li&gt;
&lt;li&gt;Includes the &lt;code&gt;UITableViewDelegate&lt;/code&gt; and &lt;code&gt;UITableViewDataSource&lt;/code&gt; properties but doesn't provide any implementations of the methods.&lt;/li&gt;
&lt;li&gt;Invokes &lt;code&gt;setEditing:animated:&lt;/code&gt; on the &lt;code&gt;UITableView&lt;/code&gt; when it is invoked on the controller.&lt;/li&gt;
&lt;li&gt;Reloads the table data and clears the selection in &lt;code&gt;viewWillAppear:&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Flashes the scroll indicators of the table in &lt;code&gt;viewDidAppear:&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I personally consider some of these "optional" and normally leave them out unless I need to use them. I normally leave out the reloading of table data altogether as I feel application logic can handle this more efficiently. What follows are the essential methods.&lt;/p&gt;

&lt;p&gt;An implementation of &lt;code&gt;loadView&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;pre&gt;- (void)loadView
{
    if (self.nibName)
    {
        [super loadView];
        NSAssert(tableView != nil, @"NIB file did not set tableView property.");
        return;
    }
    
    UITableView *newTableView =
        [[[UITableView alloc]
            initWithFrame:CGRectZero
            style:UITableViewStylePlain]
        autorelease];
    self.view = newTableView;
    self.tableView = newTableView;
}&lt;/pre&gt;

&lt;p&gt;I've hard-coded the &lt;code&gt;UITableViewStyle&lt;/code&gt; here instead of relying on a &lt;code&gt;initWithStyle:&lt;/code&gt; constructor. Since this is my code, I'm happy to select the default value I want for my program here, I don't need to specify this value at initialization.&lt;/p&gt;

&lt;p&gt;Notice that I set the &lt;code&gt;self.view&lt;/code&gt; and the &lt;code&gt;self.tableView&lt;/code&gt; separately. In &lt;code&gt;UITableViewController&lt;/code&gt;, these two properties are always the same value. I like to keep a distinction between the two in my &lt;code&gt;UITableView&lt;/code&gt; controller so that my controller can manage a wrapper view around the table view as well. Obviously in this default case, there is no wrapper, so both are set to be the same. If there &lt;em&gt;were&lt;/em&gt; both the same, I wouldn't need the &lt;code&gt;tableView&lt;/code&gt; ivar (see accessors below) I would use the same &lt;code&gt;self.view&lt;/code&gt; storage for both.&lt;/p&gt;

&lt;p&gt;The only other default code required are the &lt;code&gt;tableView&lt;/code&gt; and &lt;code&gt;setTableView:&lt;/code&gt; methods for the &lt;code&gt;tableView&lt;/code&gt; property. The only important steps here are to set the table's &lt;code&gt;delegate&lt;/code&gt; and &lt;code&gt;dataSource&lt;/code&gt; to the controller.&lt;/p&gt;

&lt;pre&gt;- (UITableView *)tableView
{
    return tableView;
}

- (void)setTableView:(UITableView *)newTableView
{
    if ([tableView isEqual:newTableView])
    {
        return;
    }
    [tableView release];
    tableView = [newTableView retain];
    [tableView setDelegate:self];
    [tableView setDataSource:self];
}&lt;/pre&gt;

&lt;h4&gt;The time display application&lt;/h4&gt;

&lt;p&gt;In the sample app, my &lt;code&gt;BaseViewController&lt;/code&gt; (a subclass of &lt;code&gt;UIViewController&lt;/code&gt;) contains methods that start an &lt;code&gt;NSTimer&lt;/code&gt; when the view appears and stop it when the view disappears.&lt;/p&gt;

&lt;p&gt;This timer fires the following method:&lt;/p&gt;

&lt;pre&gt;- (void)timerUpdate:(NSTimer *)aTimer
{
    NSDate *date = [NSDate date];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    const NSInteger unitFlags =
        NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDateComponents *components =
        [calendar components:unitFlags fromDate:date];
    
    if (![components isEqual:lastComponents])
    {
        [lastComponents release];
        lastComponents = [components retain];
        [self updateWithDateComponents:components];
    }
}&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;updateWithDateComponents:&lt;/code&gt; is empty but subclasses of &lt;code&gt;BaseViewController&lt;/code&gt; can implement it to update themselves when the time changes. In this way, every screen in my application automatically receives per-second updates.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;TimeTableViewController&lt;/code&gt; in the application is then a subclass of &lt;code&gt;BaseViewController&lt;/code&gt; which further adds &lt;code&gt;UITableViewController&lt;/code&gt;-like functionality (as shown above) and combines the two to constantly update the time components in the table.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;DetailViewController&lt;/code&gt; (which is constructed when a row is clicked) is also a subclass of &lt;code&gt;BaseViewController&lt;/code&gt; but when an &lt;code&gt;updateWithDateComponents:&lt;/code&gt; message is received, only displays the component for which it is the "detail" view.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can &lt;a href="http://cocoawithlove.googlepages.com/RecreatedTableViewController.zip"&gt;download the complete code for the RecreatingTableViewController application&lt;/a&gt; (29kB) discussed in this post.&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;UITableViewController&lt;/code&gt; exists to make working with simple tables slightly quicker, since they are the most common type of primary view on the iPhone.&lt;/p&gt;

&lt;p&gt;However, this class is merely a convenience and if your design requires it you can avoid &lt;code&gt;UITableViewController&lt;/code&gt; entirely &amp;mdash; as in this post where the inheritance worked better without using &lt;code&gt;UITableViewController&lt;/code&gt;.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-5523025999758641428?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/5523025999758641428/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=5523025999758641428" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5523025999758641428?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5523025999758641428?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/03/recreating-uitableviewcontroller-to.html" title="Recreating UITableViewController to increase code reuse" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0MCQHszeip7ImA9WxVUEkk.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-692827362982776883</id><published>2009-03-13T21:34:00.001-07:00</published><updated>2009-03-16T17:24:21.582-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-16T17:24:21.582-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Xcode" /><title>Scripted window management in Xcode</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Xcode's placement of windows and views has never entirely satisfied me. In this post, I'll show you a series of Applescripts that I use to create my own arrangement of Xcode windows so that I can choose where different kinds of documents are placed and reorganize the layout of windows with basic key commands.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;

&lt;h4&gt;Xcode's window layout options&lt;/h4&gt;

&lt;p&gt;To show multiple files in Xcode's "Default" or "All-in-one" you need to open a second window since Xcode's project window does not support two neat column panes in the project window &lt;em&gt;[edit: Yes it does. See first the first comment.]&lt;/em&gt;. This bothers me because I like to keep my windows tidy, so I found myself manually positioning these external windows a lot.&lt;/p&gt;

&lt;p&gt;Furthermore, if you have positioned your main project window to look pretty when showing an 80 to 120 character width text document, opening a fundamentally different kind of document in the window (like a Core Data .xcdatamodel) requires that you resize the project window to view the new document properly and resize back again when done.&lt;/p&gt;

&lt;p&gt;I could use the "Condensed" layout that Xcode provides which puts everything in a separate window by default &amp;mdash; but this doesn't solve the "manual repositioning" problem and puts extra columns into the tree-view of the project window which I find cluttering and unnecessary.&lt;/p&gt;

&lt;h4&gt;Choose your own layout&lt;/h4&gt;

&lt;p&gt;In an effort to address all the things I dislike about Xcode's default layouts, I decided to create a series of Applescripts that would position windows where I want them and could do so based on the type of window (source document, Find results, Build results, Core Data .xcdatamodel, etc). The result is a "virtual" all-in-one window where the panes are positioned according to my choices and I can shift documents from the left-column to the right column or to fullscreen with a basic key command.&lt;/p&gt;

&lt;p&gt;Here's a screenshot of my layout showing two edit windows in columns and the project window on the left:&lt;/p&gt;

&lt;img src="http://lh3.ggpht.com/_gfktUGS0ov0/Sbicl-mnCiI/AAAAAAAAASQ/hBhvHmiRa8w/myxcodelayout.png?imgmax=800" alt="myxcodelayout.png" border="0" width="504" height="315" /&gt;

&lt;p&gt;I clearly use a minimalist layout but the approach I will present could be used to put find and build results at the top of one column and reserve the second column for the debugger and console.&lt;/p&gt;

&lt;p&gt;The Xcode layout required is the "Default" layout but I collapse the Project window down to just the tree-view by double-clicking the "double-vertical-bar-and-arrow" icon at the right of the tree-view header.&lt;/p&gt;

&lt;h4&gt;Keyboard shortcuts and working without the toolbar&lt;/h4&gt;

&lt;p&gt;The only two toolbar items I use are the "Build Configuration" and "Active SDK" popup menus. I use the standard set in the Debug Window but for building I consider it a waste of time. There are only a few keyboard shortcuts you need for Xcode and you really should know them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;#8984;Y &amp;mdash; Build and Debug. This should be your most-used key command.&lt;/li&gt;
&lt;li&gt;&amp;#8984;&amp;#8679;D &amp;mdash; Open a file by name. Much faster than using the Project Tree for large projects.&lt;/li&gt;
&lt;li&gt;&amp;#8984;&amp;#8679;Y &amp;mdash; Show the Debug Window.&lt;/li&gt;
&lt;li&gt;&amp;#8984;&amp;#8679;F &amp;mdash; Show the Find Window.&lt;/li&gt;
&lt;li&gt;&amp;#8984;&amp;#8679;R &amp;mdash; Show the Run Console.&lt;/li&gt;
&lt;li&gt;&amp;#8984;+option+W &amp;mdash; Close all windows of the current type (fast way to close all source windows)&lt;/li&gt;
&lt;li&gt;F10 (or Control + Dashboard button on new keyboards) &amp;mdash; Show the current app's windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To this collection of keyboard shortcuts, I'll add the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;#8984;1 &amp;mdash;Position the front-most window in the first column.&lt;/li&gt;
&lt;li&gt;&amp;#8984;2 &amp;mdash;Position the front-most window in the second column.&lt;/li&gt;
&lt;li&gt;&amp;#8984;3 &amp;mdash;Position the front-most window filling the first and second columns.&lt;/li&gt;
&lt;li&gt;&amp;#8984;4 &amp;mdash;Reposition all windows based on type.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;The positioning scripts&lt;/h4&gt;

&lt;p&gt;The following is the Xcode user script for positioning the front-most window in the first column:&lt;/p&gt;

&lt;pre&gt;#! /usr/bin/osascript

set screenWidth to 1680
set screenHeight to 1050
set dockBottomPadding to 73
set dockLeftPadding to 0
set dockRightPadding to 0

set projectWindowWidth to 300
set menubarHeight to 22

set docWidth to (screenWidth - dockLeftPadding - dockRightPadding - projectWindowWidth) / 2
set leftDocBounds to {dockLeftPadding + projectWindowWidth, dockBottomPadding, screenWidth - dockRightPadding - docWidth - 1, screenHeight - menubarHeight}

tell application "Xcode"
    set bounds of item 1 of windows to leftDocBounds
end tell
&lt;/pre&gt;

&lt;p&gt;To make this work, add it to your Xcode User Scripts as Input=No Input, Directory=Selection, Output=Discard Output, Error=Display in Alert. I then set the shortcut to &amp;#8984;1. If you've never added an Xcode User Script before, I &lt;a href="http://cocoawithlove.com/2008/12/instance-variable-to-synthesized.html"&gt;explain the process more thoroughly in an earlier post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since it is difficult to get the actual screen size using Applescript (see &lt;a href="http://daringfireball.net/2006/12/display_size_applescript_the_lazy_way"&gt;John Gruber's pain in trying&lt;/a&gt;) I've hardcoded my screen size into the script. Change the width and height if your screen is a different size and change the dock padding values if your dock is a different height or placement.&lt;/p&gt;

&lt;p&gt;This much is fairly simple. Much more interesting is the "reposition everything" script:&lt;/p&gt;

&lt;pre&gt;#! /usr/bin/osascript

set screenWidth to 1680
set screenHeight to 1050
set dockBottomPadding to 73
set dockLeftPadding to 0
set dockRightPadding to 0

set projectWindowWidth to 300
set menubarHeight to 22

set docWidth to (screenWidth - dockLeftPadding - dockRightPadding - projectWindowWidth) / 2
set projectBounds to {dockLeftPadding, dockBottomPadding, projectWindowWidth + dockLeftPadding - 1, screenHeight - menubarHeight}
set leftDocBounds to {dockLeftPadding + projectWindowWidth, dockBottomPadding, screenWidth - dockRightPadding - docWidth - 1, screenHeight - menubarHeight}
set rightDocBounds to {screenWidth - dockRightPadding - docWidth, dockBottomPadding, screenWidth - dockRightPadding - 1, screenHeight - menubarHeight}
set fullDocBounds to {dockLeftPadding + projectWindowWidth, dockBottomPadding, screenWidth - dockRightPadding - 1, screenHeight - menubarHeight}

tell application "Xcode"
    set leftHalfScreenSuffixes to {"m", "c", "h", "mm", "cpp"}
    set rightHalfScreenSuffixes to {"Results", "Find", "Console"}
    set fullScreenSuffixes to {"xcdatamodel", "Debugger"}
    set processedWindows to {}
    repeat with doc in documents
        set docName to name of doc
        if (length of docName) is greater than 10 then
            set docNameMinusExtension to text 1 thru ((length of docName) - 10) of docName
        else
            set docNameMinusExtension to ""
        end if
        repeat with win in windows of doc
            set n to name of win
            try -- wrap in a try in case the window name is undefined
                set end of processedWindows to name of win
                if n is equal to docNameMinusExtension then
                    set bounds of win to projectBounds
                else
                    set extension to last item in words of n
                    if extension is in leftHalfScreenSuffixes then
                        set bounds of win to leftDocBounds
                    else if extension is in rightHalfScreenSuffixes then
                        set bounds of win to rightDocBounds
                    else if extension is in fullScreenSuffixes then
                        set bounds of win to fullDocBounds
                    end if
                end if
            end try
        end repeat
    end repeat
    repeat with win in windows
        if not (processedWindows contains name of win) then
            set n to name of win
            try -- wrap in a try in case the window name is undefined
                set extension to last item in words of n
                if extension is in leftHalfScreenSuffixes then
                    set bounds of win to leftDocBounds
                else if extension is in rightHalfScreenSuffixes then
                    set bounds of win to rightDocBounds
                else if extension is in fullScreenSuffixes then
                    set bounds of win to fullDocBounds
                end if
            end try
        end if
    end repeat
end tell
&lt;/pre&gt;

&lt;p&gt;This script iterates over the windows for each document, then over all windows not attached to a document to reach every window that Xcode has open. It then uses the window's title to decide where to place each window. Source code files are placed in the first column, results windows are placed in the second column and the Debugger is made dual column. This script also positions the Project window.&lt;/p&gt;

&lt;p&gt;The "position in the second column" and "position filling first and second columns" scripts are just like the first script but with &lt;code&gt;rightDocBounds&lt;/code&gt; and &lt;code&gt;fullDocBounds&lt;/code&gt; from the second script respectively.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;A few scripts to reposition your windows and connected to the shortcuts &amp;#8984;1 to &amp;#8984;4 is not a revolutionary idea but I don't think I was alone among Xcode programmers in continuously repositioning my windows as I opened and shut new documents and switched from debugging to editing to build results and back.&lt;/p&gt;

&lt;p&gt;These scripts only save a few seconds at a time but they make Xcode feel much more magical as windows jump to exactly where I want them to be.&lt;/p&gt;

&lt;p&gt;I doubt everyone will want to position their windows exactly as I have but these scripts should be easily adaptable to a range of different layouts &amp;mdash; just tweak the calculated bounds and the sets of Window suffixes that are placed at each bounds.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-692827362982776883?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/692827362982776883/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=692827362982776883" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/692827362982776883?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/692827362982776883?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/03/scripted-window-management-in-xcode.html" title="Scripted window management in Xcode" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUIASXY8eyp7ImA9WxVVFk4.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1037895685095082055</id><published>2009-03-08T15:41:00.001-07:00</published><updated>2009-03-09T15:25:48.873-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-09T15:25:48.873-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CoreAnimation" /><title>An Asteroids-style game in CoreAnimation, Part Four.</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;Over the last three weeks, I presented a simple 2D game using CoreAnimation. For the final post in this series, I'll look at CATransactions and why I didn't use them in the game to handle animations and I'll look at the performance of CoreAnimation as numbers of CALayers and sizes of CALayers change.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Frame-based animation&lt;/h4&gt;
&lt;p&gt;The Quartzeroids2 game (download the complete code from the &lt;a href="http://cocoawithlove.com/2009/03/asteroids-style-game-in-coreanimation.html"&gt;previous post&lt;/a&gt;) uses traditional frame-based updates to process, position and render all objects on screen. This works much like stop-motion animation as filmed with optical cameras: a frame is needed approximately every 30th of a second so the game moves all objects to their locations for this new frame (as determined by speed and trajectory) and the renderer takes a snapshot.&lt;/p&gt;

&lt;p&gt;As with stop-motion animation, the only reason this process appears smooth to the eye is because the frames are frequent enough that they run together appearing like motion.&lt;/p&gt;

&lt;p&gt;This is the traditional way that 2D games are implemented. Initially though, I wanted to handle the game in a different way. Frame-based animation has two main problems:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;The CPU must reprocess all game objects 30 times a second (or more) to place them on screen, creating a continuous burden on the CPU.&lt;/li&gt;
&lt;li&gt;Even at 30 frames a second, fast moving objects leave distinct gaps which can cause problems with collision detection.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;The following diagram illustrates the second point:&lt;/p&gt;

&lt;img src="http://lh3.ggpht.com/_gfktUGS0ov0/SbB4b9R7IoI/AAAAAAAAASI/3bGh5h28ZgY/framesversuscontinuous.png?imgmax=800" alt="framesversuscontinuous.png" border="0" width="350" height="220" /&gt;

&lt;p&gt;The blue and red balls never touch during a keyframe but if they were moving continuously would clearly collide in the middle. Such collisions could be detected by significantly increasing the frame-rate but that isn't always technically possible and would certainly make the first problem (excessive CPU usage) worse.&lt;/p&gt;

&lt;h4&gt;Continuous animation using CATransactions&lt;/h4&gt;

&lt;p&gt;What I wanted to do instead of frame-based animation was to create a continuous game instead.&lt;/p&gt;

&lt;p&gt;The idea would be: instead of the game engine reprocessing for each frame, just load the speeds and trajectories into CoreAnimation and let the animation run automatically until the next "event" (collision or user action). That way, the animation runs smoothly, the game engine performs the minimum amount of work and all collisions are mathematically perfect (since we calculate them in advance using trajectory equations instead of reading quantized data at frame update time).&lt;/p&gt;

&lt;p&gt;Continuous animation would involve taking the basic line equation (&lt;em&gt;y&lt;/em&gt; = &lt;em&gt;mx&lt;/em&gt; + &lt;em&gt;b&lt;/em&gt;) for the two bounding edges of each object's trajectory and colliding it with the bounding box of the screen and every other object's trajectory equations. Between now and that first collision each object could be animated using a CoreAnimation &lt;code&gt;CAAnimation&lt;/code&gt;, with the animations for all objects tied together using a &lt;code&gt;CATransaction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first downside to this was adding user involvement. When the user presses a key, they are changing the modelling for their player object which involves recalculating the next collision. This means that while the user is pressing a key, 30 recalculations per second may be required. On its own, this negative won't outweigh the positives. Recalculating in his manner isn't much more work than traditional frame-based collision detection which is always performed 30 frames-per-second or more &amp;mdash; and these collisions would still be mathematically perfect.&lt;/p&gt;

&lt;h5&gt;Testing CATransactions&lt;/h5&gt;

&lt;p&gt;To see how the worst case of 30 updates per second would perform, you can add &lt;code&gt;CATransaction&lt;/code&gt;-based animation to Quartzeroids2 by removing the &lt;code&gt;actionForKey:&lt;/code&gt; method from "ImageLayer.m" in the program and replacing the following code in "GameObjectLayer.m":&lt;/p&gt;

&lt;pre&gt;self.imageName = gameObjectImageName;
self.bounds = CGRectMake(0, 0, width, height);
self.position = CGPointMake(x, y);
self.transform = CATransform3DMakeRotation(angle, 0, 0, 1.0);
self.hidden = !visible;&lt;/pre&gt;

&lt;p&gt;with the &lt;code&gt;CATransaction&lt;/code&gt; based version:&lt;/p&gt;

&lt;pre&gt;double distance =
    sqrt((self.position.x - x) * (self.position.x - x) +
    (self.position.y - y) * (self.position.y - y));
BOOL wrapping = distance &gt; gameHeight;

if (wrapping)
{
    [self removeAllAnimations];
}

[CATransaction begin];
[CATransaction
    setValue:[NSNumber numberWithDouble:GAME_UPDATE_DURATION]
    forKey:kCATransactionAnimationDuration];

if (wrapping)
{
    [CATransaction
        setValue:[NSNumber numberWithBool:YES]
        forKey:kCATransactionDisableActions];
}

self.imageName = gameObjectImageName;
self.bounds = CGRectMake(0, 0, width, height);
self.position = CGPointMake(x, y);
self.transform = CATransform3DMakeRotation(angle, 0, 0, 1.0);
self.hidden = !visible;

[CATransaction commit];&lt;/pre&gt;

&lt;h5&gt;Performance-based failure&lt;/h5&gt;

&lt;p&gt;The following performance numbers are running on my 2 x 2Ghz PowerMac G5.&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Number of CALayers animated using CATransaction&lt;/td&gt;&lt;td&gt;Frames per second&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;50&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;75&lt;/td&gt;&lt;td&gt;10-25&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;&amp;lt;10&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;150&lt;/td&gt;&lt;td&gt;&amp;lt;2&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;I've given ranges since the frames per second varied significantly. This compares poorly with the &lt;code&gt;CATransaction&lt;/code&gt; disabled version, where all tests ran faster than 30 frames per second.&lt;/p&gt;

&lt;p&gt;Since each asteroid represents two separate objects and every shot fired is another object on screen, I decided that an inability to handle more than 50 objects smoothly was unacceptable and discarded the &lt;code&gt;CATransaction&lt;/code&gt;-based approach.&lt;/p&gt;

&lt;p&gt;Clearly, &lt;code&gt;CATransaction&lt;/code&gt;-based animation has a significant amount of work to perform and this work increases more-than-linearly (greater than &lt;code&gt;O(n)&lt;/code&gt;) with respect to the number of objects on screen. In CoreAnimation, you aren't expected to regenerate thousands of animations each second like this. I leave open the possibility that there's a modified approach that could still make this work but I didn't want to spend further time investigating.&lt;/p&gt;

&lt;h4&gt;Testing the render system in Quartzeroids2&lt;/h4&gt;

&lt;p&gt;To perform a series of performance tests on Quartzeroids2's rendering system, I removed the &lt;code&gt;PlayerObject&lt;/code&gt; from the game, disabled the &lt;code&gt;AsteroidLayerObject&lt;/code&gt; added for each asteroid by the &lt;code&gt;GameController&lt;/code&gt; and used the &lt;code&gt;ASTEROID_LARGE_SIZE&lt;/code&gt; and &lt;code&gt;ASTEROID_BASE_NUM&lt;/code&gt; values to control the size and number of objects on the screen. I measured frame rates with the Quartz Debug frame meter.&lt;/p&gt;

&lt;h5&gt;Object size tests&lt;/h5&gt;

&lt;p&gt;The following test all involved 100 &lt;code&gt;CALayer&lt;/code&gt;s on screen. My graphics card is an ATI Radeon X800 with 256MB VRAM.&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Width and Height of CALayer in pixels&lt;/td&gt;&lt;td&gt;Frames per second&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;110&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;440&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;660&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;770&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;880&lt;/td&gt;&lt;td&gt;&amp;lt; 5&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Once you exceed the available video memory in CoreAnimation, frame rate immediately plummets. Some new Macs have double the VRAM that I have but many still ship with 256MB VRAM as standard, so these numbers are probably indicative of the average among newer machines.&lt;/p&gt;

&lt;h5&gt;Object count tests&lt;/h5&gt;

&lt;p&gt;The following tests all involved 11 pixel by 11 pixel objects.&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Number of CALayers on screen&lt;/td&gt;&lt;td&gt;Frames per second&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;200&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;300&lt;/td&gt;&lt;td&gt;&amp;gt; 33&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;400&lt;/td&gt;&lt;td&gt;20&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;500&lt;/td&gt;&lt;td&gt;18&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;600&lt;/td&gt;&lt;td&gt;12&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;700&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;800&lt;/td&gt;&lt;td&gt;&amp;lt; 5&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Profiling the 800 object version revealed CPU time was mostly spent in CALayer updating layer positions &amp;mdash; so this would appear to be a basic CPU bound situation for CoreAnimation on the test machine. On newer Mac Pros, I wouldn't be surprised if object counts over 1000 were possible at 30 frames per second.&lt;/p&gt;

&lt;h5&gt;Other CALayer limitations&lt;/h5&gt;

&lt;p&gt;Depending on your graphics card, you may have a maximum texture size. On my ATI Radeon X800, that size is 2048 by 2048. Any texture bigger than 2048 in any CALayer with a native size bigger than 2048 in any direction will result in an empty white square when rendered, instead of the expected texture. &lt;code&gt;CALayer&lt;/code&gt; does output an error when this occurs:&lt;/p&gt;

&lt;pre&gt;CoreAnimation: 2049 by 2049 image is too large for GPU, ignoring&lt;/pre&gt;

&lt;p&gt;Newer cards have maximum texture sizes of 4096 and even 8192 pixels. A hard limit here for your target systems could be difficult to know.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;CoreAnimation is incredibly capable as a 2D renderer. I have spent this post discussing its limits but that is not because I consider its capabilities limiting but because I am impressed by how much it can do. With CoreAnimation layers, you can render hundreds of objects, each of which can be hundreds of pixels big, without paying any attention to performance &amp;mdash; you can simply let CoreAnimation handle it.&lt;/p&gt;

&lt;p&gt;Obviously, for the Quarteroids2 game I developed, most of this testing was irrelevant but it may prove useful to anyone looking to use CoreAnimation in a more ambitious manner.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1037895685095082055?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/1037895685095082055/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=1037895685095082055" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1037895685095082055?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1037895685095082055?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/03/asteroids-style-game-in-coreanimation_08.html" title="An Asteroids-style game in CoreAnimation, Part Four." /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C04ARX8yfCp7ImA9WxVWGU0.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-6158123192776638391</id><published>2009-03-01T02:05:00.001-08:00</published><updated>2009-03-01T02:05:44.194-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-01T02:05:44.194-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CoreAnimation" /><title>An Asteroids-style game in CoreAnimation, Part Three.</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;How would you write an arcade-style 2D game in CoreAnimation? I'll show you how to write a resolution independent, high-speed, model-view-controller designed, Asteroids-style arcade game using CoreAnimation as the screen renderer. In this third of four parts, I add the logic for the game and game objects and present the finished code for the project.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;From renderer to game&lt;/h4&gt;
&lt;p&gt;In the &lt;a href="http://cocoawithlove.com/2009/02/asteroids-style-game-in-coreanimation_22.html"&gt;previous post&lt;/a&gt;, I presented a rendering system using CoreAnimation layers (&lt;code&gt;CALayer&lt;/code&gt;). To complete the game, we now need to add the game logic.&lt;/p&gt;

&lt;p&gt;For this Asteroids-style game, the game logic will be very simple but will need to include the following components:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;User control of the ship&lt;/li&gt;
&lt;li&gt;Shooting and shot/asteroid collision detection and destruction.&lt;/li&gt;
&lt;li&gt;Player/asteroid collision and a finite number of player "lives"&lt;/li&gt;
&lt;li&gt;Level logic, so that a new, harder level is started when the previous one is cleared.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;With the game logic added, the code for the project will be complete.&lt;/p&gt;

&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/SaoyndAFdlI/AAAAAAAAASA/mmss1tJk6bo/quartzeroidspart3.png?imgmax=800" alt="quartzeroidspart3.png" border="0" width="379" height="232" /&gt;
&lt;p style="text-align:center;"&gt;&lt;em&gt;A screenshot of the game with shots and asteroid destruction.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;User control&lt;/h4&gt;

&lt;p&gt;Most games treat keyboard input in a different manner to applications. Instead of reading &lt;code&gt;keyDown:&lt;/code&gt; messages, including the &lt;code&gt;isARepeat&lt;/code&gt; messages (whose delay and frequency are specified in the System Preferences), games simply want the state of specific keys at a given time. e.g. "Is the 'thrust' key pressed?"&lt;/p&gt;

&lt;p&gt;To provide the game with what it wants, I created a subclass of &lt;code&gt;NSView&lt;/code&gt; to use as the &lt;code&gt;contentView&lt;/code&gt; of the window. The sole purpose of this view subclass is to read key event messages passed to the window. When &lt;code&gt;keyDown:&lt;/code&gt; messages are received, boolean values on the &lt;code&gt;GameData&lt;/code&gt; object are set. When the &lt;code&gt;keyUp:&lt;/code&gt; message is received, the boolean values are cleared. In this way, we store the keyboard state so we can read it in an asynchronous manner whenever it is needed.&lt;/p&gt;

&lt;p&gt;The implementation of the &lt;code&gt;keyDown:&lt;/code&gt; method follows.&lt;/p&gt;

&lt;pre&gt;- (void)keyDown:(NSEvent *)event
{
    NSString *characters = [event characters];
    if ([characters length] == 1 &amp;&amp; ![event isARepeat])
    {
        const NSInteger ESCAPE_KEY_CODE = 27;
        
        unichar character = [characters characterAtIndex:0];
        if (character == NSLeftArrowFunctionKey)
        {
            [[GameData sharedGameData] setLeftKeyDown:YES];
        }
        else if (character == NSRightArrowFunctionKey)
        {
            [[GameData sharedGameData] setRightKeyDown:YES];
        }
        else if (character == NSUpArrowFunctionKey)
        {
            [[GameData sharedGameData] setUpKeyDown:YES];
        }
        else if (character == ' ')
        {
            [[GameData sharedGameData] setShootKeyDown:YES];
        }
        else if (character == ESCAPE_KEY_CODE)
        {
            [gameController togglePause:self];
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Notice that Apple provide constants for higher level keys (like the arrow keys) but you are expected to handle ASCII codes (like the Escape key) yourself. You can get these from the ASCII manual page (&lt;code&gt;man ascii&lt;/code&gt; in a terminal window). Be careful to avoid the octal set &amp;mdash; I have no idea how it earned first position in this file.&lt;/p&gt;

&lt;p&gt;To respond to these new keyboard flags, I will create a subclass of &lt;code&gt;GameObject&lt;/code&gt; (the generic class representing an object in the game) named &lt;code&gt;PlayerObject&lt;/code&gt; to handle the player's ship. The real purpose of this subclass will be to add game-logic related behaviors. The primary location for adding behaviors will be an override of the parent class' &lt;code&gt;updateWithTimeInterval:&lt;/code&gt; that supplements the default behavior with player-specific movement and interaction.&lt;/p&gt;

&lt;p&gt;Here is the code to handle the "thrust" key (the up arrow):&lt;/p&gt;
&lt;pre&gt;if ([GameData sharedGameData].upKeyDown)
{
    double scaledAcceleration = timeInterval * PLAYER_ACCELERATION;
    double dX = speed * cos(trajectory) + scaledAcceleration * cos(angle + M_PI_2);
    double dY = speed * sin(trajectory) + scaledAcceleration * sin(angle + M_PI_2);
    
    speed = sqrt(dX * dX + dY * dY);
    trajectory = acos(dX / speed);
    if (dY &lt; 0)
    {
        trajectory *= -1;
    }
    
    if (speed &gt; PLAYER_MAX_SPEED)
    {
        speed = PLAYER_MAX_SPEED;
    }
}&lt;/pre&gt;

&lt;p&gt;This code is some basic trigonometry to add the ship's current &lt;code&gt;speed&lt;/code&gt;/&lt;code&gt;trajectory&lt;/code&gt; vector to the new thrust vector, limiting the ship's maximum speed. The actual &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; of the ship is modified by invoking the &lt;code&gt;super&lt;/code&gt; implementation (which applies this &lt;code&gt;speed&lt;/code&gt; and &lt;code&gt;trajectory&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Model-view-controller design note&lt;/strong&gt;&lt;br/&gt;
This approach to key control is not typical of an application. In an application, a user-interface controller chooses the target object and sends the keyboard control directly to that object. In this game, the user-interface sets keyboard state in a game-accessible location and game objects choose whether to incorporate that state into their own. This behavior is good for a game because it allows the game objects to choose their own interaction logic but games represent a special case in this regard.&lt;/blockquote&gt;

&lt;h4&gt;Firing shots&lt;/h4&gt;

&lt;p&gt;The other key aspect of user control in the game is the ability to fire shots.&lt;/p&gt;

&lt;p&gt;Once again, I will use a &lt;code&gt;GameObject&lt;/code&gt; subclass to handle the shots. These &lt;code&gt;ShotObject&lt;/code&gt;s will be created in the &lt;code&gt;PlayerObject&lt;/code&gt;'s &lt;code&gt;updateWithTimeInterval:&lt;/code&gt; method, since they will need to incorporate speed and trajectory information from the &lt;code&gt;PlayerObject&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following code fires a shot when the user presses the 'shoot' key (spacebar).&lt;/p&gt;

&lt;pre&gt;ShotObject *newShot =
    [[ShotObject alloc]
        initWithX:x + 0.5 * width * cos(angle + M_PI_2)
        y:y + 0.5 * height * sin(angle + M_PI_2)];
[[GameData sharedGameData]
    addGameObject:newShot
    forKey:[[GameData sharedGameData] keyForShotAtIndex:nextShotIndex]];

nextShotIndex = (nextShotIndex + 1) % PLAYER_MAX_SHOTS;
[[GameData sharedGameData]
    setGameDataObject:[NSNumber numberWithInteger:nextShotIndex]
    forKey:GAME_DATA_NEXT_SHOT_INDEX_KEY];

double dX = speed * cos(trajectory) + PLAYER_SHOT_SPEED * cos(angle + M_PI_2);
double dY = speed * sin(trajectory) + PLAYER_SHOT_SPEED * sin(angle + M_PI_2);
double shotSpeed = sqrt(dX * dX + dY * dY);
double shotTrajectory = acos(dX / shotSpeed);
if (dY &lt; 0)
{
    shotTrajectory *= -1;
}
newShot.speed = shotSpeed;
newShot.trajectory = shotTrajectory;

shotCooldown = PLAYER_SHOT_COOLDOWN;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;initWithX:y:&lt;/code&gt; line creates the &lt;code&gt;ShotObject&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;addGameObject:forKey:&lt;/code&gt; part adds it to the game. &lt;code&gt;GameObject&lt;/code&gt;s are all stored by a single key in this game but I use the &lt;code&gt;keyForShotAtIndex:&lt;/code&gt; to create this key from a prefix ("shot") and a suffix (the shot's index) so that I can extract information about the object from its key.&lt;/p&gt;

&lt;p&gt;This is a lazy approach to organizing game objects and any larger game would want to store its objects in a more metadata rich storage system. Better organizations might include:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;metadata methods on each game object so you can query each object about what it is&lt;/li&gt;
&lt;li&gt;additionally storing game objects in dictionaries keyed by type or other essential category information&lt;/li&gt;
&lt;li&gt;storing game objects in richly indexed system like an SQLite database (which is then accessible by any column)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;setGameDataObject:forKey:&lt;/code&gt; line sets the number of shots that the player has fired in the &lt;code&gt;GameData&lt;/code&gt;'s generic object storage. This will allow us to limit the number of shots fired by the player to &lt;code&gt;PLAYER_MAX_SHOTS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next code is some more trigonometry to apply the ship's speed and trajectory to the shot. Then finally the &lt;code&gt;shotCooldown&lt;/code&gt; value is set. This is a simple counter (decremented on each &lt;code&gt;updateWithTimeInterval:&lt;/code&gt;) which will prevent another shot being fired while it is greater than zero (allowing us to set the minimum time between shots).&lt;/p&gt;

&lt;h4&gt;Collisions&lt;/h4&gt;

&lt;p&gt;Last week's code contained a very simple main update loop that called the &lt;code&gt;updateWithInterval:&lt;/code&gt; method on all &lt;code&gt;GameObject&lt;/code&gt;s. This time, we expand the update loop to the following:&lt;/p&gt;

&lt;pre&gt;- (void)updateLevel:(NSTimer *)aTimer
{
    if (lastUpdate)
    {
        frameDuration = [[NSDate date] timeIntervalSinceDate:lastUpdate];
        [lastUpdate release];
        lastUpdate = [[NSDate alloc] init];
    }
    else
    {
        frameDuration = GAME_UPDATE_DURATION;
    }
    
    NSArray *allKeys = [gameObjects allKeys];
    for (NSString *gameObjectKey in allKeys)
    {
        [gameObjects willChangeValueForKey:gameObjectKey];
        GameObject *gameObject = [gameObjects objectForKey:gameObjectKey];
    
        if ([gameObject collide])
        {
            [gameObjects removeObjectForKey:gameObjectKey];
        }
    }
    for (NSString *gameObjectKey in allKeys)
    {
        GameObject *gameObject = [gameObjects objectForKey:gameObjectKey];
        if (!gameObject)
        {
            [gameObjects didChangeValueForKey:gameObjectKey];
            continue;
        }
        
        if ([gameObject updateWithTimeInterval:frameDuration])
        {
            [gameObjects removeObjectForKey:gameObjectKey];
        }
        [gameObjects didChangeValueForKey:gameObjectKey];
    }
}&lt;/pre&gt;

&lt;p&gt;We time the duration between updates ourselves, even though we ask the &lt;code&gt;NSTimer&lt;/code&gt; to invoke us every 0.03 seconds. This allows us to keep the animation as smooth as possible even if the timer is delayed or frames start taking longer than 0.03 seconds to complete.&lt;/p&gt;

&lt;p&gt;After this, we iterate over all the &lt;code&gt;GameObject&lt;/code&gt;s twice: once to process collisions and once to update positions. The reason for this separation is to ensure that all of the game objects are at the same moment in time when we process them for collisions &amp;mdash; if we processed collisions during the update of positions then everything already updated for position would be 1 frame ahead of objects not yet processed when collisions are tested.&lt;/p&gt;

&lt;p&gt;I chose to perform collisions before the update so that the collision applies to what the user can currently see (rather than what they will see after CoreAnimation updates).&lt;/p&gt;

&lt;p&gt;Performing collisions is very simple &amp;mdash; especially in this game since I'm only performing bounding box collisions. The collision code in &lt;code&gt;ShotObject&lt;/code&gt; which tests for collisions between shots and asteroids follows.&lt;/p&gt;

&lt;pre&gt;- (BOOL)collide
{
    NSString *collision = [[[GameData sharedGameData]
            collideObjectsWithKeyPrefix:GAME_ASTEROID_KEY_BASE
            withObjectForKey:keyInGameData]
        anyObject];
    if (collision)
    {
        [AsteroidObject spawnNewAsteroidsReplacing:collision];
        return YES;
    }
    return NO;
}&lt;/pre&gt;

&lt;p&gt;Once again, I'm using the prefix metadata in my game object keys to select asteroids for collisions.&lt;/p&gt;

&lt;p&gt;The collision code lives on the &lt;code&gt;GameData&lt;/code&gt; class.&lt;/p&gt;

&lt;pre&gt;- (NSSet *)collideObjectsWithKeyPrefix:(NSString *)prefix withObjectForKey:(NSString *)testObjectKey
{
    GameObject *testObject = [gameObjects objectForKey:testObjectKey];
    NSMutableSet *result = [NSMutableSet set];
    
    NSRect testRect = NSMakeRect(
        testObject.x - 0.5 * testObject.width,
        testObject.y - 0.5 * testObject.height,
        testObject.width,
        testObject.height);
    
    for (NSString *gameObjectKey in gameObjects)
    {
        if ([gameObjectKey isEqualToString:testObjectKey] ||
            [gameObjectKey rangeOfString:prefix].location != 0)
        {
            continue;
        }
        
        GameObject *gameObject = [gameObjects objectForKey:gameObjectKey];
        NSRect gameRect = NSMakeRect(
            gameObject.x - 0.5 * gameObject.width,
            gameObject.y - 0.5 * gameObject.height,
            gameObject.width,
            gameObject.height);
        
        if (NSIntersectsRect(gameRect, testRect))
        {
            [result addObject:gameObjectKey];
        }
    }
    
    return result;
}&lt;/pre&gt;

&lt;p&gt;This code creates a bounding rectangle from the &lt;code&gt;GameObject&lt;/code&gt; specified by the &lt;code&gt;testObjectKey&lt;/code&gt; and collides it with all objects stored by keys starting with &lt;code&gt;prefix&lt;/code&gt; that aren't the &lt;code&gt;testObject&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;This code returns the whole set of colliding objects &amp;mdash; overkill since the game only ever uses one at a time &amp;mdash; but functional and easily fast enough for our purposes.&lt;/p&gt;

&lt;h4&gt;Tying it all together&lt;/h4&gt;

&lt;p&gt;We can control the ship, shoot and hit asteroids. There's a bit more that's in the game that you can see if you want:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;The shots animate through 5 frames and expire after a fixed amount of time. I chose to store the current animation frame in the game data and handle the animation there (instead of in the view like the asteroid animation was in the last post). I wanted to show that animation state could be part of the game data if it is data-related (this animation isn't really data-related so I have some regrets).&lt;/li&gt;
&lt;li&gt;The asteroids start at random locations in a ring around the player for each level and spawn 3 smaller asteroids when shot, each of which travels in a random direction with a random rotation.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Instead of dwelling on that, I'll jump to the last part of the game logic: the game (including lives) and the levels.&lt;/p&gt;

&lt;p&gt;I want the following behaviors in the game:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;The player begins with 3 lives at level 1.&lt;/li&gt;
&lt;li&gt;Each level starts with a "Prepare for level X..." message for a few seconds before displaying the contents of the level and starting normal play.&lt;/li&gt;
&lt;li&gt;Every time the player loses a life (collides with an asteroid) the game displays an "X lives remaining..." message for a few seconds before positioning the player in the middle of the screen and starting normal play again.&lt;/li&gt;
&lt;li&gt;When the number of lives hits zero, a "Game Over" message is displayed and the game is stopped.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The data containing the number of lives and the current level are just objects in the &lt;code&gt;gameData&lt;/code&gt; dictionary. Creating a new level creates (3 + levelNumber) asteroids and places the player in the center. The messages are just a string, set using a specific &lt;code&gt;GAME_DATA_MESSAGE_KEY&lt;/code&gt;, also on the &lt;code&gt;gameData&lt;/code&gt; dictionary. These values are displayed by using bindings to connect them to ordinary &lt;code&gt;NSTextField&lt;/code&gt;s in the window.&lt;/p&gt;

&lt;p&gt;More interesting is that the game needs to change its underlying behavior when the player dies or a new level begins.&lt;/p&gt;

&lt;p&gt;The solution I chose is to maintain two different update loops for the two basic behaviors. The &lt;code&gt;updateLevel:&lt;/code&gt; method I've already shown is the "normal" update method. A second update method named &lt;code&gt;readyCountdown:&lt;/code&gt; will be used to do nothing (not update the &lt;code&gt;GameObject&lt;/code&gt;s) for a few seconds while a message is displayed, before returning to the regular update method.&lt;/p&gt;

&lt;p&gt;Along with &lt;code&gt;newGame&lt;/code&gt;, &lt;code&gt;newLevel&lt;/code&gt; and &lt;code&gt;endGame&lt;/code&gt; methods, the game now has the ability to transition between different gameplay states.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;&lt;a href="http://cocoawithlove.googlepages.com/Quartzeroids2Part3.zip"&gt;Download the complete, finished game Quartzeroids2.zip&lt;/a&gt; (239 kB).&lt;/blockquote&gt;

&lt;p&gt;With the window and design from the first part, the rendering and layers from the second part and now the game logic, the game is complete. Download it, build it, play it and be underwhelmed by its simplicity.&lt;/p&gt;

&lt;p&gt;In the final part, I'll present analysis of CoreAnimation's utility as a game rendering engine. I'll look at some features of CoreAnimation that I didn't use, including features that impacted negatively on performance. I'll also look at how CoreAnimation performance changes as the number of render objects is increased.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-6158123192776638391?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/6158123192776638391/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=6158123192776638391" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/6158123192776638391?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/6158123192776638391?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/03/asteroids-style-game-in-coreanimation.html" title="An Asteroids-style game in CoreAnimation, Part Three." /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUAHQ3c8fyp7ImA9WxVWFEk.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-5638063900965529541</id><published>2009-02-22T19:49:00.001-08:00</published><updated>2009-02-23T18:48:52.977-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-23T18:48:52.977-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CoreAnimation" /><title>An Asteroids-style game in CoreAnimation, Part Two.</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;How would you write an arcade-style 2D game in CoreAnimation? I'll show you how to write a resolution independent, high-speed, model-view-controller designed, Asteroids-style arcade game using CoreAnimation as the screen renderer. In this second of four parts, I'll create basic objects in the game and their corresponding CoreAnimation Layers on screen.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;We have a window&lt;/h4&gt;
&lt;p&gt;In the &lt;a href="http://cocoawithlove.com/2009/02/asteroids-style-game-in-coreanimation.html"&gt;previous post&lt;/a&gt; I proposed an Asteroids-style game in CoreAnimation and explained the basic design of the Quartzeroids2 game&lt;/p&gt; 
&lt;p&gt;I showed the code to construct and scale the window. It has a blue gradient background and can switch between fullscreen and windowed modes.&lt;/p&gt;
&lt;p&gt;Now, we need to put something in that window.&lt;/p&gt;

&lt;img src="http://lh6.ggpht.com/_gfktUGS0ov0/SaC7ONnp_oI/AAAAAAAAAR4/PD6sRrk4o5M/objectsonscreen.png?imgmax=800" alt="objectsonscreen.png" border="0" width="406" height="209" /&gt;
&lt;p style="text-align:center"&gt;Objects placed on screen in this part.&lt;/p&gt;

&lt;h4&gt;Image Layers&lt;/h4&gt;

&lt;p&gt;Drawing in the window is done using CoreAnimation layers. If you looked closely at how the window background was drawn in Part One, you'll notice that it was a &lt;code&gt;CALayer&lt;/code&gt;, drawn using a single image:&lt;/p&gt;

&lt;pre&gt;NSImage *image = [NSImage imageNamed:imageName];
[image
    drawInRect:NSRectFromCGRect([self bounds])
    fromRect:[image alignmentRect]
    operation:NSCompositeSourceOver
    fraction:1.0];&lt;/pre&gt;

&lt;p&gt;Since this single image is a PDF made from vector (not bitmapped) components, this means that the layer can be drawn at any resolution without aliasing effects from resizing. In fact, the background PDF isn't even the right aspect ratio and Cocoa happily reshapes it for us. The added processing time to render a PDF, relative to bitmap, doesn't really matter since CoreAnimation only renders the CALayer once, then reuses the existing texture.&lt;/p&gt;

&lt;h4&gt;Game Objects and Layers&lt;/h4&gt;

&lt;p&gt;Placing a game-related object on screen will require two different components: the &lt;code&gt;GameObject&lt;/code&gt; and the &lt;code&gt;GameObjectLayer&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;GameObject&lt;/h5&gt;

&lt;p&gt;The &lt;code&gt;GameObject&lt;/code&gt; is the version of the object as handled in the &lt;code&gt;GameData&lt;/code&gt;. Since the game logic is responsible for deciding the size, positioning, speed, trajectory and in some cases the image and angle of rotation of the object, these properties will all be properties of the &lt;code&gt;GameObject&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GameObject&lt;/code&gt;s are held by the &lt;code&gt;GameData&lt;/code&gt; object. It tracks all of the &lt;code&gt;GameObject&lt;/code&gt;s in a dictionary, so all &lt;code&gt;GameObject&lt;/code&gt;s can be accessed at any time by their unique key in the &lt;code&gt;GameData&lt;/code&gt;'s &lt;code&gt;gameObjects&lt;/code&gt; dictionary.&lt;/p&gt; 

&lt;blockquote&gt;&lt;strong&gt;Resolution independence:&lt;/strong&gt;&lt;br/&gt;The biggest quirk about how I decided to implement the &lt;code&gt;GameObject&lt;/code&gt; is that it is totally resolution independent. All coordinates and sizes are measured in units where &lt;code&gt;1.0&lt;/code&gt; is the height of the game window. So the coordinates &lt;code&gt;(0, 0)&lt;/code&gt;, &lt;code&gt;(0.5 * GAME_ASPECT, 0.5)&lt;/code&gt; and &lt;code&gt;(GAME_ASPECT, 1.0)&lt;/code&gt; are the bottom-left corner, center and top-right corners of the screen respectively (&lt;code&gt;GAME_ASPECT&lt;/code&gt; is the window aspect ratio: width of the window divided by the height).&lt;/blockquote&gt;

&lt;p&gt;With the &lt;code&gt;GameObject&lt;/code&gt; being just a long list of Objective-C properties, most of the code in &lt;code&gt;GameObject&lt;/code&gt; exists to set, modify or update those properties. The biggest common "update" that needs to be performed is to move the object according to its speed and trajectory and "wrap" the object if it goes off the edge of the screen:&lt;/p&gt;

&lt;pre&gt;- (BOOL)updateWithTimeInterval:(NSTimeInterval)timeInterval
{
    x += timeInterval * speed * cos(trajectory);
    y += timeInterval * speed * sin(trajectory);
    
    if (x &gt; GAME_ASPECT + (0.5 + GAME_OBJECT_BOUNDARY_EXCESS) * width)
    {
        x = -0.5 * width;
    }
    else if (x &lt; -(0.5 + GAME_OBJECT_BOUNDARY_EXCESS) * width)
    {
        x = GAME_ASPECT + 0.5 * width;
    }
    
    if (y &gt; 1.0 + (0.5 + GAME_OBJECT_BOUNDARY_EXCESS) * height)
    {
        y = -0.5 * height;
    }
    else if (y &lt; -(0.5 + GAME_OBJECT_BOUNDARY_EXCESS) * height)
    {
        y = 1.0 + 0.5 * height;
    }
    
    return NO;
}&lt;/pre&gt;

&lt;p&gt;This method returns "NO" to indicate that it was not deleted during the update. This won't be used until next week when we add more of the game logic.&lt;/p&gt;

&lt;p&gt;The objects are allowed to exceed the edge of the bounds by &lt;code&gt;GAME_OBJECT_BOUNDARY_EXCESS&lt;/code&gt;. This ensures that they don't feel like they disappeared with a tiny portion still onscreen.&lt;/p&gt;

&lt;h5&gt;GameObjectLayer&lt;/h5&gt;

&lt;p&gt;The &lt;code&gt;GameObjectLayer&lt;/code&gt; is a subclass of &lt;code&gt;ImageLayer&lt;/code&gt;, using that class' code to render a single image to a &lt;code&gt;CALayer&lt;/code&gt;. A &lt;code&gt;GameObjectLayer&lt;/code&gt; contains a key that identifies its corresponding &lt;code&gt;GameObject&lt;/code&gt; in the &lt;code&gt;GameData&lt;/code&gt;. It observes the &lt;code&gt;GameData&lt;/code&gt;'s &lt;code&gt;gameObjects&lt;/code&gt; dictionary for changes on that key and when any of the observed &lt;code&gt;GameObject&lt;/code&gt; properties change, the &lt;code&gt;GameObjectLayer&lt;/code&gt; will update itself accordingly.&lt;/p&gt;

&lt;p&gt;The result is that the only substantial work required in the &lt;code&gt;GameObjectLayer&lt;/code&gt; is updating itself when a change in the &lt;code&gt;GameObject&lt;/code&gt; is observed.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GameObjectLayer&lt;/code&gt;'s &lt;code&gt;observeValueForKeyPath:ofObject:change:context:&lt;/code&gt; method is smart enough to realize when the &lt;code&gt;GameObject&lt;/code&gt; changes to &lt;code&gt;NSNull&lt;/code&gt; (i.e. is deleted) and autodeletes.&lt;/p&gt;

&lt;pre&gt;- (void)update
{
    GameObject *gameObject = [[[GameData sharedGameData] gameObjects] objectForKey:gameObjectKey];
    double gameHeight = [[GameData sharedGameData] gameHeight];

    NSString *gameObjectImageName = gameObject.imageName;
    double x = gameObject.x * gameHeight;
    double y = gameObject.y * gameHeight;
    double width = gameObject.width * gameHeight;
    double height = gameObject.height * gameHeight;
    double angle = gameObject.angle;
    BOOL visible = gameObject.visible;

    self.imageName = gameObjectImageName;
    self.bounds = CGRectMake(0, 0, width, height);
    self.position = CGPointMake(x, y);
    self.transform = CATransform3DMakeRotation(angle, 0, 0, 1.0);
    self.hidden = !visible;
}&lt;/pre&gt;

&lt;p&gt;Notice that the &lt;code&gt;GameObjectLayer&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; resolution independent, so the &lt;code&gt;GameObject&lt;/code&gt; coordinates are multiplied through by the &lt;code&gt;gameHeight&lt;/code&gt; to convert them to coordinates in the layer hierarchy.&lt;/p&gt;

&lt;h5&gt;Controller code to bind them&lt;/h5&gt;

&lt;p&gt;The final element required to make &lt;code&gt;GameObject&lt;/code&gt;s and &lt;code&gt;GameObjectLayer&lt;/code&gt;s work together is controller code to construct the &lt;code&gt;GameObjectLayer&lt;/code&gt; for each &lt;code&gt;GameObject&lt;/code&gt; as it appears.&lt;/p&gt;

&lt;p&gt;I chose to do this by making the &lt;code&gt;GameData&lt;/code&gt; send a &lt;code&gt;GameObjectNewNotification&lt;/code&gt; every time a new &lt;code&gt;GameObject&lt;/code&gt; is added to the &lt;code&gt;gameObjects&lt;/code&gt; dictionary. The GameController observes this notification with the following method:&lt;/p&gt;

&lt;pre&gt;- (void)createImageLayerForGameObject:(NSNotification *)notification
{
    NSString *gameObjectKey = [notification object];
    
    GameObjectLayer *newLayer =
        [[[GameObjectLayer alloc]
            initWithGameObjectKey:gameObjectKey]
        autorelease];

    [CATransaction begin];
    [CATransaction
        setValue:[NSNumber numberWithBool:YES]
        forKey:kCATransactionDisableActions];
    [backgroundLayer addSublayer:newLayer];
    [CATransaction commit];
}&lt;/pre&gt;

&lt;p&gt;Transactions are disabled so the layer doesn't fade in, it appears immediately.&lt;/p&gt;

&lt;h4&gt;Letting the view reinterpret the data&lt;/h4&gt;

&lt;p&gt;If you ran the program with the above code, the asteroid would not look like the slightly soccerball texture shown in the screenshot at the top and it would not spin. The asteroid would be a smooth gradient circle. This is because the the asteroid shown in the screenshot is made of two components: the non-rotating "asteroid-back" which provides a consistent lightsource-like effect and the "asteroid-front" which is a spinning second layer on top of the back layer.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://lh6.ggpht.com/_gfktUGS0ov0/SaDFk3KemlI/AAAAAAAAAR8/KqWXHT0DAqw/asteroid.png?imgmax=800" alt="asteroid.png" border="0" width="389" height="198" /&gt;

&lt;p&gt;The &lt;code&gt;GameData&lt;/code&gt; only contains the basic bounds information, which is mapped onto the "asteroid-back" by default. How can we add the second spinning layer for the purposes of display?&lt;/p&gt;

&lt;p&gt;We could add the second layer as another object in the game but since I want this layer for the purposes of display (it has no real game-logic impact), I decided to handle it a different way.&lt;/p&gt;

&lt;p&gt;After the &lt;code&gt;[CATransaction commit];&lt;/code&gt; line in the previous code sample, I include the code:&lt;/p&gt;

&lt;pre&gt;if ([gameObjectKey rangeOfString:GAME_ASTEROID_KEY_BASE].location == 0)
{
    AsteroidFrontLayer *asteroidFrontLayer =
        [[[AsteroidFrontLayer alloc]
            initWithGameObjectKey:gameObjectKey]
        autorelease];
    
    [CATransaction begin];
    [CATransaction
        setValue:[NSNumber numberWithBool:YES]
        forKey:kCATransactionDisableActions];
    [backgroundLayer addSublayer:asteroidFrontLayer];
    [CATransaction commit];
}&lt;/pre&gt;

&lt;p&gt;So I look to see if the new &lt;code&gt;GameObject&lt;/code&gt; is added to the &lt;code&gt;gameObjects&lt;/code&gt; dictionary using a key that starts with &lt;code&gt;GAME_ASTEROID_KEY_BASE&lt;/code&gt;. If it does, then I create a second layer that tracks the same underlying &lt;code&gt;GameObject&lt;/code&gt;. This second layer is an &lt;code&gt;AsteroidFrontLayer&lt;/code&gt; instead of the generic &lt;code&gt;GameObjectLayer&lt;/code&gt;. This &lt;code&gt;AsteroidFrontLayer&lt;/code&gt; class is a subclass of &lt;code&gt;GameObjectLayer&lt;/code&gt; that overrides the &lt;code&gt;imageName&lt;/code&gt; to be "asteroid-front" and applies a rotation to the layer on each update.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the &lt;a href="http://cocoawithlove.googlepages.com/Quartzeroids2Part2.zip"&gt;Quartzeroids2 Part 2 project&lt;/a&gt; (225kB) which demonstrates the classes presented in this post.&lt;/blockquote&gt;

&lt;p&gt;The project for this part shows the &lt;code&gt;GameObject&lt;/code&gt;, &lt;code&gt;GameObjectLayer&lt;/code&gt; and &lt;code&gt;AsteroidFrontLayer&lt;/code&gt; in a simple, non-interactive display. To show everything on screen, the &lt;code&gt;GameData&lt;/code&gt; class contains a &lt;code&gt;newGame&lt;/code&gt; method which constructs some sample objects and then starts a timer running to call the &lt;code&gt; updateWithTimeInterval:&lt;/code&gt; methods repeatedly.&lt;/p&gt;

&lt;p&gt;Now that we can draw our objects on screen, Part 3 will add user-interaction and game logic.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-5638063900965529541?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/5638063900965529541/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=5638063900965529541" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5638063900965529541?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5638063900965529541?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/02/asteroids-style-game-in-coreanimation_22.html" title="An Asteroids-style game in CoreAnimation, Part Two." /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0IFRXY5eip7ImA9WxVXGU8.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1696293703597149277</id><published>2009-02-17T14:55:00.001-08:00</published><updated>2009-02-17T18:51:54.822-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-17T18:51:54.822-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CoreAnimation" /><title>An Asteroids-style game in CoreAnimation, Part One.</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;How would you write an arcade-style 2D game in CoreAnimation? Over the next few weeks, I'll show you how to write a resolution independent, high-speed, model-view-controller designed, Asteroids-style arcade game using CoreAnimation as the screen renderer. In this first of four parts, I'll detail the concept for the overall application and show you how to create a resolution independent window for the game.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;

&lt;img src="http://lh4.ggpht.com/_gfktUGS0ov0/SZqtCxsqupI/AAAAAAAAARw/1Fr7C-ZovOk/quartzeroids2.png?imgmax=800" alt="quartzeroids2.png" border="0" width="420" height="300" /&gt;
&lt;p style="text-align:center"&gt;A screenshot of the finished game&lt;/p&gt;

&lt;h4&gt;CoreAnimation as a game renderer&lt;/h4&gt;
&lt;p&gt;Drawing on the Mac is normally done through either CoreGraphics or OpenGL. OpenGL is fast, supports 2D and 3D and is already used in many games. However, OpenGL is a low-level, pure-C API, so even simple rendering and animating of 2D surfaces can require a whole library of code to accomplish.&lt;/p&gt;

&lt;p&gt;CoreGraphics and the &lt;code&gt;NSView&lt;/code&gt; hierarchy are a whole library of well-written code. They are clean to use and support a wide range of features without needing to write them yourself. Sadly, CoreGraphics is not ideal for games since it does not easily render 30 fullscreen frames per second (the minimum standard for action games) &amp;mdash; even with Quartz Extreme and the other improvements Apple has added since Mac OS X 10.0.&lt;/p&gt;

&lt;p&gt;This is where CoreAnimation comes in. Apple introduced CoreAnimation in Mac OS X 10.5 (Leopard) to dramatically accelerate the animation of 2D rectangular textures. Since it integrates so well into the existing CoreGraphics and &lt;code&gt;NSView&lt;/code&gt; hierarchy on the Mac, it suddenly gives CoreGraphics a way of delivering 30 (or more) fullscreen frames per second and makes a writing a game possible using nothing more than the Foundation, AppKit and QuartzCore libraries.&lt;/p&gt;

&lt;h4&gt;Quartzeroids One&lt;/h4&gt;

&lt;p&gt;The application I'll present over the next few weeks will be similar to an experiment I wrote about 8 years ago. Back then, the application was named Quartzeroids and it was an experiment to see if &lt;code&gt;NSView&lt;/code&gt;s were fast enough to use for a 2D Asteroids game. The code was not good &amp;mdash; if you find it out in the wild, keep your distance and call animal control.&lt;/p&gt;

&lt;p&gt;Were &lt;code&gt;NSView&lt;/code&gt;s fast enough for this type of animation? No, not really. At 640 by 480, the game played at 15 frames-per-second on my iMac G3 500Mhz. Computer and operating-system improvements have improved this (newer Intel Macs can now render this old 640 by 480 screen size at more than 30 frames per second) but even newer machines cannot maintain good frame rates at proper fullscreen resolutions of 1920 by 1200 using this approach.&lt;/p&gt;

&lt;h4&gt;Quartzeroids Two&lt;/h4&gt;

&lt;p&gt;Since Apple released CoreAnimation 15 months ago, I had been wanting to revisit the idea. To further increase the difficulty, I decided the project should also contain the following features:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Resolution independence (all vector graphics and completely resizeable).&lt;/li&gt;
&lt;li&gt;Proper model-view-controller implementation where the "game-state" is the model and the view is free to reinterpret the state for the purposes of display.&lt;/li&gt;
&lt;li&gt;Fullscreen or windowed mode for display.&lt;/li&gt;&lt;/ul&gt;

&lt;h4&gt;Rough design&lt;/h4&gt;

&lt;p&gt;A rough block diagram of the program would look like this:&lt;/p&gt;

&lt;img src="http://lh3.ggpht.com/_gfktUGS0ov0/SZq1JJxcI6I/AAAAAAAAAR0/poo2eCp_FLM/rect3155.png?imgmax=800" alt="rect3155.png" border="0" width="480" height="362" /&gt;

&lt;p&gt;The decisions I think were most significant are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;There is not a one-to-one relationship between objects in the Game Data and Layers in the Window.&lt;/li&gt;
&lt;li&gt;The updates to the Game Data are triggered by the Game Data's own timer, not directly by the controller (which can start and stop but nothing further).&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The second point is most significant when the Game Data is compared to a normal application document. A normal document never updates itself &amp;mdash; it only changes when instructions are sent from a controller. In a game however, choosing when to update is a part of the game logic (which I have included in the model) so the controller shown here is left with only the simplest level of control.&lt;/p&gt;

&lt;p&gt;I spent some time deliberating about whether to make the &lt;code&gt;GameData&lt;/code&gt; a normal document object or a singleton. A normal document style object can be swapped with another document or recreated. A singleton is lazier and simpler since it doesn't need to be connected to every object which needs to access it (since it is globally accessible). Ultimately, the convenience of a singleton won over the hypothetical flexibility of a normal document object since the game will only ever be strictly single instance.&lt;/p&gt;

&lt;h4&gt;A resolution independent, constant aspect-ratio view&lt;/h4&gt;

&lt;p&gt;To get the code started for the project, I'll show you how the top level of the &lt;code&gt;CALayer&lt;/code&gt; hierarchy (named &lt;code&gt;backgroundLayer&lt;/code&gt; in the application since it shows the background for the game) is implemented inside the &lt;code&gt;contentView&lt;/code&gt; for the window.&lt;/p&gt;

&lt;p&gt;The two hardest constraints for the &lt;code&gt;backgroundView&lt;/code&gt; are maintaining a constant aspect ratio and maintaining a constant internal coordinates when the surrounding window resizes or reshapes.&lt;/p&gt;

&lt;pre&gt;- (void)updateContentViewFrame:(NSNotification *)notification
{
    double gameWidth = [[GameData sharedGameData] gameWidth];
    double gameHeight = [[GameData sharedGameData] gameHeight];
    
    NSSize contentSize = [contentView bounds].size;

    NSSize aspectSize = contentSize;
    double scale;
    if ((aspectSize.width / aspectSize.height) &gt; (gameWidth / gameHeight))
    {
        scale = aspectSize.height / gameHeight;
        aspectSize.width = aspectSize.height * (gameWidth / gameHeight);
    }
    else
    {
        scale = aspectSize.width / gameWidth;
        aspectSize.height = aspectSize.width * (gameHeight / gameWidth);
    }
    
    [CATransaction begin];
    [CATransaction
        setValue:(id)kCFBooleanTrue
        forKey:kCATransactionDisableActions];
    backgroundLayer.transform = CATransform3DMakeScale(scale, scale, 1.0);
    backgroundLayer.frame =
        CGRectMake(
            0.5 * (contentSize.width - aspectSize.width),
            0.5 * (contentSize.height - aspectSize.height),
            aspectSize.width,
            aspectSize.height);
    [CATransaction commit];

    [contentView becomeFirstResponder];
}&lt;/pre&gt;

&lt;p&gt;The GameController adds this method as an observer of the &lt;code&gt;contentView&lt;/code&gt;'s &lt;code&gt;NSViewFrameDidChangeNotification&lt;/code&gt;. The &lt;code&gt;gameWidth&lt;/code&gt; and &lt;code&gt;gameHeight&lt;/code&gt; methods on the &lt;code&gt;GameData&lt;/code&gt; objecct are programmed to return values with a 16:10 ratio (matching common widescreen computer aspect ratios). The &lt;code&gt;aspectSize&lt;/code&gt; calculated here is then the largest size that obeys this ratio and can fit inside the &lt;code&gt;contentView&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;CATransform3DMakeScale&lt;/code&gt; transform, applied to the &lt;code&gt;backgroundLayer&lt;/code&gt; before the frame is set, causes the &lt;code&gt;backgroundLayer&lt;/code&gt; to always treat its internal coordinates as though they are &lt;code&gt;gameWidth&lt;/code&gt; by &lt;code&gt;gameHeight&lt;/code&gt;. This will mean that any layers our game adds to the &lt;code&gt;backgroundLayer&lt;/code&gt;'s subview hierarchy will always render at a constant fraction of the &lt;code&gt;backgroundLayer&lt;/code&gt;'s size. Order is important here: apply the transform after the frame is set and it will behave differently.&lt;/p&gt;

&lt;p&gt;The other required behavior of the window is switching to fullscreen and back. This is another task which became extremely simple in Mac OS X 10.5:&lt;/p&gt;

&lt;pre&gt;- (IBAction)toggleFullscreen:(id)sender
{
    if ([contentView isInFullScreenMode])
    {
        [contentView exitFullScreenModeWithOptions:nil];
    }
    else
    {
        [contentView
            enterFullScreenMode:[[contentView window] screen]
            withOptions:nil];
        
        for (NSView *view in [NSArray arrayWithArray:[contentView subviews]])
        {
            [view removeFromSuperview];
            [contentView addSubview:view];
        }
    }
}&lt;/pre&gt;

&lt;p&gt;The "&lt;code&gt;for&lt;/code&gt;" loop is an annoying necessity: if you don't do this for a CoreAnimation layer-enabled NSView, then all child &lt;code&gt;NSView&lt;/code&gt;s will fail to update correctly after a switch to fullscreen.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download &lt;a href="http://cocoawithlove.googlepages.com/Quartzeroids2Part1.zip"&gt;Quartzeroids2 Part 1 (20kb)&lt;/a&gt; which shows the full implementation of the window, &lt;code&gt;contentView&lt;/code&gt; and &lt;code&gt;backgroundLayer&lt;/code&gt;.&lt;/blockquote

&lt;p&gt;A simple as this game is, it is too big to describe in one post &amp;mdash; this is as far as I'll get this week. I've presented a few goals, a rough design and the window management code for the game.&lt;/p&gt;

&lt;p&gt;In the next post, I'll start to put objects in the game and layers in the window.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1696293703597149277?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/1696293703597149277/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=1696293703597149277" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1696293703597149277?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1696293703597149277?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/02/asteroids-style-game-in-coreanimation.html" title="An Asteroids-style game in CoreAnimation, Part One." /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UDSH87cSp7ImA9WxVXEU0.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-2988550519723496643</id><published>2009-02-07T23:48:00.001-08:00</published><updated>2009-02-08T07:01:19.109-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-08T07:01:19.109-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><title>Breadth-first traversal of a graph of Objective-C objects</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;If you have a collection of interconnected objects in Objective-C, what is the best way to traverse them all in order from nearest to furthest? Are the &lt;code&gt;NSMutableSet&lt;/code&gt; methods good for tracking already-visited nodes? How much overhead does an &lt;code&gt;NSMutableArray&lt;/code&gt; FIFO queue impose relative to a depth-first search (which doesn't require a FIFO queue)? Does &lt;code&gt;NSMutableArray&lt;/code&gt; perform better if objects are pushed onto the front, or the back? In this post, I present answers to these questions and more.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Graph theory&lt;/h4&gt;
&lt;p&gt;In programming, a graph is any collection of connected data objects.&lt;/p&gt;

&lt;p&gt;If that information was new to you, then I suggest you read this Wikipedia page: &lt;a href="http://en.wikipedia.org/wiki/Graph_(computer_science)"&gt;Graph (computer science)&lt;/a&gt;, then read every page to which it links, then for each of those pages, also read every page to which they link. Come back to this page once the irony is apparent.&lt;/p&gt;

&lt;p&gt;The two common means of processing nodes in a graph are depth-first and breadth-first traversal. Breadth-first graph traversals are normally slightly harder to write than depth-first traversals because we have the added requirement of a maintaining a FIFO queue to handle the nodes to be processed.&lt;/p&gt;

&lt;p&gt;When all the nodes in the graph are Objective-C objects and an &lt;code&gt;NSMutableArray&lt;/code&gt; is used to maintain the FIFO queue, what is the fastest way to traverse? I tested a few different approaches to see which would work best.&lt;/p&gt;

&lt;h4&gt;The graph used for testing&lt;/h4&gt;

&lt;p&gt;All my tests were on graphs where each node of the graph was connected to two more nodes until the center layer of the graph, at which point pairs of nodes were subsequently connected to a single node until the graph converged back to a single node.&lt;/p&gt;

&lt;p&gt;An example of this graph structure (shown horizontally so layers are aligned in columns) with two increasing layers and two decreasing layers is:&lt;/p&gt;

&lt;img src="http://lh3.ggpht.com/_gfktUGS0ov0/SY512JgUAxI/AAAAAAAAARo/28Eh_XEZp2Y/graph.png?imgmax=800" alt="graph.png" border="0" width="250" height="209" /&gt;

&lt;p&gt;Since there are two increasing layers and two decreasing layers, I called this a "half-depth" of 2. I will refer to the size of all subsequent graphs by their "half-depth".&lt;/p&gt;

&lt;p&gt;All nodes are objects of the following class:&lt;/p&gt;

&lt;pre&gt;@interface Node : NSObject
{
    NSSet *linkedNodes;
}
@property (nonatomic, retain) NSSet *linkedNodes;
@end&lt;/pre&gt;

&lt;p&gt;These classes don't store any useful information but that's not the point of these tests: I'm testing traversal performance only.&lt;/p&gt;

&lt;h4&gt;Initial approach&lt;/h4&gt;

&lt;p&gt;The basic algorithm is:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;create a set to track already-visited nodes&lt;/li&gt;
&lt;li&gt;create an array to queue nodes-to-process&lt;/li&gt;
&lt;li&gt;for every node (in order) in the nodes-to-process array:
&lt;ol&gt;&lt;li&gt;get the set of nodes linked to the current node&lt;/li&gt;
&lt;li&gt;exclude nodes that we've already visited from the linked set&lt;/li&gt;
&lt;li&gt;add non-excluded, linked nodes to the nodes-to-process array&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first code I wrote implementing this algorithm was:&lt;/p&gt;

&lt;pre&gt;NSMutableSet *visitedNodes = [NSMutableSet setWithObject:startingNode];
NSMutableArray *queue = [NSMutableArray arrayWithObject:startingNode];

while ([queue count] &gt; 0)
{
    NSMutableSet *newNodes =
        [[((Node *)[queue lastObject]).linkedNodes mutableCopy] autorelease];
    [newNodes minusSet:visitedNodes];
    
    [visitedNodes unionSet:newNodes];
    [queue
        replaceObjectsInRange:NSMakeRange(0, 0)
        withObjectsFromArray:[newNodes allObjects]];
    
    [queue removeLastObject];
}&lt;/pre&gt;

&lt;p&gt;This code uses &lt;code&gt;NSMutableSet&lt;/code&gt;'s own set-operators to exclude already visited nodes. It also pushes new objects onto the front of the &lt;code&gt;queue&lt;/code&gt; and pops each node for processing off the end.&lt;/p&gt;

&lt;p&gt;So, how did this approach perform? In a word: terrible &amp;mdash; and it's the fault of &lt;code&gt;-[NSMutableSet minusSet:]&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Lesson 1:&lt;/strong&gt;&lt;br&gt;Only ever use &lt;code&gt;[setOne minusSet:setTwo]&lt;/code&gt; if &lt;code&gt;setOne&lt;/code&gt; is bigger than &lt;code&gt;setTwo&lt;/code&gt;. This method runs in O(&lt;em&gt;n&lt;/em&gt;) time, where &lt;em&gt;n&lt;/em&gt; is the size of &lt;code&gt;setTwo&lt;/code&gt;. In the above code, where &lt;code&gt;visitedNodes&lt;/code&gt; can be orders of magnitude bigger than &lt;code&gt;newNodes&lt;/code&gt; it is much faster to iterate over &lt;code&gt;newNodes&lt;/code&gt; and exclude nodes found in &lt;code&gt;visitedNodes&lt;/code&gt; ourselves. That way we run in O(&lt;em&gt;m&lt;/em&gt;) time, where &lt;em&gt;m&lt;/em&gt; is the size of &lt;code&gt;newNodes&lt;/code&gt; (and is actually small and constant for this test case).&lt;/blockquote&gt;

&lt;p&gt;The method &lt;code&gt;minusSet:&lt;/code&gt; really should iterate over the smaller set between the receiver and the parameter. However, since it doesn't we must avoid it.&lt;/p&gt;

&lt;h4&gt;Front-to-back or back-to-front&lt;/h4&gt;

&lt;p&gt;The next problem to address: is it faster to push objects onto the front of an &lt;code&gt;NSMutableArray&lt;/code&gt; and pop them off the end, or to push them onto the end and pop them off the front?&lt;/p&gt;

&lt;p&gt;The following is the push onto front:&lt;p&gt;

&lt;pre&gt;while ([queue count] &gt; 0)
{
    NSSet *newNodes = ((Node *)[queue lastObject]).linkedNodes;
    for (Node *newNode in newNodes)
    {
        if (![visitedNodes containsObject:newNode])
        {
            [visitedNodes addObject:newNode];
            [queue insertObject:newNode atIndex:0];
        }
    }

    [queue removeLastObject];
}&lt;/pre&gt;

&lt;p&gt;This is the push onto back:&lt;/p&gt;

&lt;pre&gt;while ([queue count] &gt; 0)
{
    NSSet *newNodes = ((Node *)[queue objectAtIndex:0]).linkedNodes;
    for (Node *newNode in newNodes)
    {
        if (![visitedNodes containsObject:newNode])
        {
            [visitedNodes addObject:newNode];
            [queue addObject:newNode];
        }
    }

    [queue removeObjectAtIndex:0];
}&lt;/pre&gt;

&lt;p&gt;The result, testing over graph half-depths of 8, 12, 16 and 20 (from 766 to 3145726 nodes) is that push onto end (the second one) is consistently 5% faster.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Lesson 2:&lt;/strong&gt;&lt;br&gt;An add to the end of an &lt;code&gt;NSMutableArray&lt;/code&gt; is the only operation that works quickly &amp;mdash; most other operations are consistently slower. If the number of operations is equal, favor algorithms that add to the end of the array.&lt;/blockquote&gt;

&lt;h4&gt;Other questions tested&lt;/h4&gt;

&lt;h5&gt;Will local NSAutoreleasePools help small loops like this?&lt;/h5&gt;

&lt;p&gt;Wrapping the body of the above loops in an &lt;code&gt;NSAutoreleasePool&lt;/code&gt; to release storage locally resulted in a 25% increase in time taken.&lt;/p&gt;

&lt;p&gt;The inside of these loops don't autorelease any memory (&lt;code&gt;NSMutableArray&lt;/code&gt; and &lt;code&gt;NSMutableSet&lt;/code&gt; maintain their own memory manually) so the autorelease pool is wasted effort.&lt;/p&gt;

&lt;h5&gt;Is an NSOperationQueue for the FIFO queue faster?&lt;/h5&gt;

&lt;p&gt;Moving the content of the loop into an &lt;code&gt;NSOperation&lt;/code&gt; object and pushing each operation into an &lt;code&gt;NSOperationQueue&lt;/code&gt; to traverse the graph made the overall traversal approximately 100 times slower.&lt;/p&gt;

&lt;p&gt;The extra work involved in creating each operation object, then having &lt;code&gt;NSOperationQueue&lt;/code&gt; distribute the jobs over different CPUs (I have a 2 x PPC G5 CPU machine) and waiting for each thread to start and end is a lot of overhead.&lt;/p&gt;

&lt;p&gt;Additionally, while &lt;code&gt;NSOperationQueue&lt;/code&gt; is a FIFO queue, the jobs only run in-order if we set the &lt;code&gt;maxConcurrentOperationCount&lt;/code&gt; to 1, so we're not really gaining anything from using the &lt;code&gt;NSOperationQueue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NSOperationQueue&lt;/code&gt; is intended for independent (threadable) operations of a non-trivial size. The inside of this loop doesn't meet that expectation.&lt;/p&gt;

&lt;h5&gt;How much overhead does the FIFO queue impose?&lt;/h5&gt;

&lt;p&gt;The only way to examine this is to run a depth-first search using a recursive algorithm.&lt;/p&gt;

&lt;pre&gt;void RecursivelyTraverse(Node *node)
{
    NSSet *newNodes = node.linkedNodes;
    for (Node *newNode in newNodes)
    {
        if (![recursiveSet containsObject:newNode])
        {
            [recursiveSet addObject:newNode];
            RecursivelyTraverse(newNode);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;The result, over half-depths of 8, 12, 16 and 20 is that the recursive algorithm is consistently twice as fast.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Lesson 3:&lt;/strong&gt;&lt;br&gt;Using &lt;code&gt;NSMutableArray&lt;/code&gt; as a FIFO queue imposes a constant additional time per node. In this trivial test, the additional time amounted to half the computation for the node but if you have significant additional computations to perform per node, the overhead of the FIFO queue may be insignificant relative to the remainder of your algorithm.&lt;/blockquote&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download the test code I used: &lt;a href="http://cocoawithlove.googlepages.com/FIFOQueues.zip"&gt;FIFOQueues.zip&lt;/a&gt; (46kB)&lt;/blockquote&gt;

&lt;p&gt;Even in such a simple algorithm, there are clearly some lessons to learn. The biggest surprise for me was that I couldn't trust &lt;code&gt;minusSet:&lt;/code&gt; to work in the most efficient manner. I think I'll need to submit a bug for this to Apple.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NSMutableArray&lt;/code&gt;s are not symmetric front-to-back, although the difference is minor enough that it may won't always matter.&lt;/p&gt;

&lt;p&gt;Tools like &lt;code&gt;NSOperationQueue&lt;/code&gt; are there to help multi-threading (to an extent) but don't work well on tiny snippets of code like this. Small loops like this would vectorize better than parallelize (SSE or Altivec) &amp;mdash; but you can't vectorize loops with Objective-C method invocations so that still isn't an option here.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-2988550519723496643?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/2988550519723496643/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=2988550519723496643" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/2988550519723496643?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/2988550519723496643?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/02/breadth-first-traversal-of-graph-of.html" title="Breadth-first traversal of a graph of Objective-C objects" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEQNSXY_fCp7ImA9WxVQFEo.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-1823415532724273557</id><published>2009-02-01T00:19:00.001-08:00</published><updated>2009-02-01T00:19:58.844-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-01T00:19:58.844-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Xcode" /><category scheme="http://www.blogger.com/atom/ns#" term="Foundation" /><category scheme="http://www.blogger.com/atom/ns#" term="fun hacks" /><title>Interprocess communication: snooping, intercepting and subverting</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;When Xcode is running, Interface Builder seems to magically know which classes, methods and variables are available. Where does Interface Builder get this information? How can you recreate this effect when editing source files in an external editor without Xcode running? This is the story of how I investigated the communication between Xcode and Interface Builder, so that I could recreate it for myself.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Xcode and Interface Builder, sitting in a tree...&lt;/h4&gt;
&lt;p&gt;Prior to Mac OS X 10.5 (Snowless Leopard), if you made a change to your classes, &lt;code&gt;IBActions&lt;/code&gt; or &lt;code&gt;IBOutlets&lt;/code&gt;, you needed to manually instruct Interface Builder to re-read the relevant header files before these changes were visible in Interface Builder.&lt;/p&gt;

&lt;p&gt;With Xcode 3 and Interface Builder this has changed. If you add a new class to a project in Xcode, it is immediately available in class lists when you switch to Interface Builder. Similarly, change an &lt;code&gt;IBAction&lt;/code&gt; or &lt;code&gt;IBOutlet&lt;/code&gt; in Xcode, save the header file and switch to Interface Builder: your changes are immediately visible.&lt;/p&gt;

&lt;p&gt;And yet, if you quit Xcode and edit the same files in an external editor, Interface Builder doesn't automatically detect the changes. Clearly, Interface Builder is using something other than basic file monitoring to detect the changes.&lt;/p&gt;

&lt;h4&gt;NSDistributedNotificationCenter&lt;/h4&gt;

&lt;p&gt;The simplest way for applications in Mac OS X to communicate is through the distributed notification center, &lt;code&gt;NSDistributedNotificationCenter&lt;/code&gt; in Foundation or &lt;code&gt;CFNotificationCenterRef&lt;/code&gt; (initialized with &lt;code&gt;CFNotificationCenterGetDistributedCenter&lt;/code&gt;) in CoreFoundation. This allows applications to broadcast dictionaries of objects to any application interested in listening.&lt;/p&gt;

&lt;p&gt;To see if Xcode is communicating to Interface Builder using a &lt;code&gt;NSDistributedNotificationCenter&lt;/code&gt;, I needed to configure the process "distnoted" (the daemon which manages the &lt;code&gt;NSDistributedNotificationCenter&lt;/code&gt;) to log notifications so I could see if anything relevant is broadcast.&lt;/p&gt;

&lt;p&gt;Apple's &lt;a href="http://developer.apple.com/technotes/tn2004/tn2124.html"&gt;Technical Note TN2124: Mac OS X Debugging Magic&lt;/a&gt; explains &lt;em&gt;some&lt;/em&gt; of what's needed. On the command line:&lt;/p&gt;

&lt;pre&gt;sudo touch /var/log/do_dnserver_log&lt;/pre&gt;

&lt;p&gt;Apple's documentation leaves out the next (required) steps:&lt;/p&gt;

&lt;pre&gt;sudo touch /var/log/dnserver.log
sudo chown daemon /var/log/dnserver.log&lt;/pre&gt;

&lt;p&gt;and then restart.&lt;/p&gt;

&lt;p&gt;Sadly for my investigation, this isn't how Xcode communicates to Interface Builder. Looking at the log when Xcode and Interface Builder are started, reveals nothing relevant from either program.&lt;/p&gt;

&lt;h4&gt;NSPortNameServer&lt;/h4&gt;

&lt;p&gt;I observed the next clue to how Xcode and Interface Builder communicate by starting two copies of each. In this setup, a new class created in the first instance of Xcode will be visible in both instances of Interface Builder but a new class created in the second instance of Xcode will not be detected by either copy of Interface Builder.&lt;/p&gt;

&lt;p&gt;This type of behavior is typical of named port connections.&lt;/p&gt;

&lt;p&gt;A quick Mac OS X lesson: almost all inter-process communication on the Mac is built on Mach Ports underneath. Mach Ports are a way to pass messages (blocks of data) between processes.&lt;/p&gt;

&lt;p&gt;The easiest way to for a process advertise a Mach Port so that other processes may connect to it, is to give it a name. Network names are registered using &lt;code&gt;NSNetService&lt;/code&gt; (Bonjour) but on a single host (as is far more likely in this case) network names are registered through &lt;code&gt;NSPortNameServer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NSPortNameServer&lt;/code&gt; is, in turn, handled by "launchd" (the daemon that Apple created to replace init, cron, inetd and others). So to see if the &lt;code&gt;NSPortNameServer&lt;/code&gt; supposition was correct, I needed to get "launchd" to output log information about Port Names.&lt;/p&gt;

&lt;p&gt;Again, I followed &lt;a href="http://developer.apple.com/technotes/tn2004/tn2124.html"&gt;Technical Note TN2124: Mac OS X Debugging Magic&lt;/a&gt; to learn how to do this:&lt;/p&gt;

&lt;pre&gt;sudo launchctl log level debug&lt;/pre&gt;

&lt;p&gt;And once again, the information contained in the Tech Note turned out to be insufficient. Apple really need to update this Tech Note.&lt;/p&gt;

&lt;p&gt;I wrote a program to send thousands of port name lookups on random names but no logging was output. However, I could see that the "syslog" process (the process that records logging information) was very busy but it wasn't recording any information anywhere.&lt;/p&gt;

&lt;p&gt;This is a typical "syslog.conf" problem: you must direct "syslog" information for the relevant "facility" and "level" to a destination. Unfortunately, the "facility" name that Apple gives for "launchd" in Tech Note TN2124 is wrong. Instead, I appended a "&lt;code&gt;*.debug&lt;/code&gt;" line to my "syslog.conf" file and sent the output to /var/log/debug.log instead.&lt;/p&gt;

&lt;p&gt;This finally worked: "launchd" information (and debug information from other processes) found its way to the debug log file.&lt;/p&gt;

&lt;p&gt;Finding the correct piece of information in this haystack looked like an impossible task until I started Interface Builder without Xcode running:&lt;/p&gt;

&lt;pre&gt;Mach service lookup failed: PBXProjectWatcherServerConnection-3.1.2&lt;/pre&gt;

&lt;p&gt;It doesn't follow Apple's own naming policy for Port Names (which would be something more like "com.apple.Xcode.projectwatcherserverconnection.3.1.2") but at least it is clear about its function.&lt;/p&gt;

&lt;h4&gt;NSConnection&lt;/h4&gt;

&lt;p&gt;At this point, the data sent over the Mach Port could be anything. How do you work out the format? I hoped that Apple used an &lt;code&gt;NSConnection&lt;/code&gt; since the Cocoa libraries will handle this automatically for me.&lt;/p&gt;

&lt;p&gt;Fortunately, running the following line of Cocoa Objective-C:&lt;/p&gt;

&lt;pre&gt;id rootObject =
    [NSConnection rootProxyForConnectionWithRegisteredName:
        @"PBXProjectWatcherServerConnection-3.1.2" host:nil];&lt;/pre&gt;

&lt;p&gt;cleanly returned an object of type &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt;, revealing that yes, this is a regular &lt;code&gt;NSConnection&lt;/code&gt; served over the Mach Port.&lt;/p&gt;

&lt;h4&gt;Recreating PBXProjectWatcherManager&lt;/h4&gt;

&lt;p&gt;The final step in replacing Xcode's role in keeping Interface Builder up-to-date with changes was to recreate &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt;. The easiest way to get this working, is to use &lt;a href="http://iphone.freecoder.org/classdump_en.html"&gt;class-dump&lt;/a&gt; to tell us what methods &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt; implements.&lt;/p&gt;

&lt;p&gt;Running class-dump directly on Xcode.app was no real help (Xcode.app doesn't directly contain most of Xcode's functionality &amp;mdash; it's in shared libraries). Using Activity Monitor (or lsof on the command-line) to inspect the Open Files of Xcode reveals all the shared libraries that Xcode uses. Most of these libraries live in /Developer/Library/PrivateFrameworks, so I ran the following script in that directory:&lt;/p&gt;

&lt;pre&gt;foreach f (*.framework)
  class-dump $f &gt; ~/Desktop/`basename $f .framework`.h
end&lt;/pre&gt;

&lt;p&gt;to generate header file descriptions of each framework on the desktop. "DevToolsInterface.h" turned out to contain the description of the &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Then it was a matter of working out which methods of &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt; are invoked and what they needed to return. So I created two projects: one to advertise its own &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt; under the name "PBXProjectWatcherServerConnection-3.1.2" and listen as Interface Builder connected and one to connect to Xcode's version of the same and work out the correct responses.&lt;/p&gt;

&lt;h4&gt;Final solution&lt;/h4&gt;

&lt;p&gt;The result is that Interface Builder invokes the following:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;td&gt;Method invoked&lt;/td&gt;&lt;td&gt;Required response&lt;/td&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;openProjectsContainingFile:&lt;/code&gt;&lt;/td&gt;&lt;td&gt;An &lt;code&gt;NSString&lt;/code&gt; containing a URI to any Projects that contain a file with the specified path.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;pathOfProject:&lt;/code&gt;&lt;/td&gt;&lt;td&gt;An &lt;code&gt;NSString&lt;/code&gt; containing the file path for the specified Project URI.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;nameOfProject:&lt;/code&gt;&lt;/td&gt;&lt;td&gt;An &lt;code&gt;NSString&lt;/code&gt; containing the project name for the specified Project URI.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;targetsInProject:&lt;/code&gt;&lt;/td&gt;&lt;td&gt;An &lt;code&gt;NSArray&lt;/code&gt; of &lt;code&gt;NSString&lt;/code&gt; containing the UUIDs for all targets in the specified Project URI.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;nameOfTarget:inProject:&lt;/code&gt;&lt;/td&gt;&lt;td&gt;An &lt;code&gt;NSString&lt;/code&gt; containing the target name for the specified target UUID.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;filesOfTypes:inTarget:ofProject:&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Types is normally &lt;code&gt;nil&lt;/code&gt; so the response is an &lt;code&gt;NSArray&lt;/code&gt; of &lt;code&gt;NSString&lt;/code&gt; containing file paths to all files contained in the target.&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Apparently, Interface Builder gets all the header file paths for all targets that use a given XIB file and monitors these files itself for changes. Experimental testing indicates that all that is required to replace Xcode's role in this case is to return these Project, Target and File values and Interface Builder will handle the rest (parsing the header files for information it requires).&lt;/p&gt;

&lt;p&gt;Interface Builder re-requests these values every time it is brought to the front, so it polls the "PBXProjectWatcherServerConnection-3.1.2" server, rather than implementing any automated form of observation (despite observation methods on &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt;). My guess is that this is more robust if either end of the &lt;code&gt;NSConnection&lt;/code&gt; crashes.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;I hope I've been informative about interprocess communication on the Mac and techniques for monitoring and intercepting these communications.&lt;/p&gt;

&lt;p&gt;These techniques presented in this post are only useful for intercepting standard Cocoa communication techniques.&lt;/p&gt;

&lt;p&gt;Obviously, implementing your own "PBXProjectWatcherServerConnection-3.1.2" server would require care. It isn't sending complicated information but you would need to update it every time Xcode is updated and there are dozens of other methods in the &lt;code&gt;PBXProjectWatcherManager&lt;/code&gt; that may play a role I didn't uncover in this brief investigation.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-1823415532724273557?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/1823415532724273557/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=1823415532724273557" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1823415532724273557?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/1823415532724273557?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/02/interprocess-communication-snooping.html" title="Interprocess communication: snooping, intercepting and subverting" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUcDSX07eip7ImA9WxJSGU4.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-804840528352435764</id><published>2009-01-23T22:38:00.001-08:00</published><updated>2009-05-09T23:31:18.302-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T23:31:18.302-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa Touch" /><title>Multiple virtual pages in a UIScrollView with just 2 child views</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;The &lt;code&gt;UIScrollView&lt;/code&gt; and &lt;code&gt;UIPageControl&lt;/code&gt; in Cocoa Touch allow for user interfaces with multiple panning pages. The sample project that Apple provides (PageControl) keeps all child views for every page in a lazily loaded array. I'll show you how you can implement this using just two child views, no matter how many virtual pages you wish to represent.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;First, something completely different...&lt;/h4&gt;
&lt;p&gt;Last week, &lt;a href="http://www.unpossible.com/"&gt;Dan Grigsby&lt;/a&gt; of &lt;a href="http://mobileorchard.com"&gt;Mobile Orchard&lt;/a&gt; interviewed me about a post I wrote on &lt;a href="http://cocoawithlove.com/2008/11/automated-user-interface-testing-on.html"&gt;Automated user interface testing on the iPhone&lt;/a&gt;. He posted the &lt;a href="http://www.mobileorchard.com/interview-with-matt-gallagher-author-of-the-cocoa-with-love-blog/"&gt;podcast of the interview online earlier this week&lt;/a&gt;, so I recommend you go listen if you're interested in the Director's Commentary for that earlier post.&lt;/p&gt;

&lt;h4&gt;Back to this post...&lt;/h4&gt;
&lt;p&gt;This week, I'm presenting the following application:&lt;/p&gt;
&lt;img src="http://lh5.ggpht.com/_gfktUGS0ov0/SXqkesFUANI/AAAAAAAAARc/Qs7wa5hXwws/pagingscrollview.png?imgmax=800" alt="pagingscrollview.png" border="0" width="336" height="284" /&gt;
&lt;p&gt;The black region is a &lt;code&gt;UIScrollView&lt;/code&gt; with &lt;code&gt;pagingEnabled&lt;/code&gt; set to &lt;code&gt;YES&lt;/code&gt;. The dots at the bottom are a &lt;code&gt;UIPageControl&lt;/code&gt; indicating the number of pages in the &lt;code&gt;UIScrollView&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Apple's sample application "PageControl" presents a similar user interface that loads a different &lt;code&gt;UIViewController&lt;/code&gt; and &lt;code&gt;UIView&lt;/code&gt; for each of the pages in the &lt;code&gt;UIScrollView&lt;/code&gt;. I'll show you how you can create the same effect using exactly two child &lt;code&gt;UIViewController&lt;/code&gt;s and &lt;code&gt;UIView&lt;/code&gt;s &amp;mdash; a "current" and the "next" view which leap around out-of-view to fill in each new page as the scrolling reaches it.&lt;/p&gt;

&lt;h4&gt;Fast display, slow content&lt;/h4&gt;

&lt;p&gt;The approach I will display is optimized for views that can redisplay quickly, once their data is loaded. The data may or may not be slow-to-load data so it is important that it is not loaded as part of the view.&lt;/p&gt;

&lt;p&gt;Data is therefore loaded and cached in a separate, data-specific class. In the sample app, it will be a class named &lt;code&gt;DataSource&lt;/code&gt; that holds an array of page titles and page text &amp;mdash; simple in this case but it's just a sample app.&lt;/p&gt;

&lt;p&gt;Holding your data in a view-independent class is basic program design &amp;mdash; as good programmers, I'm sure you always do this and never, ever have your &lt;code&gt;UIViewController&lt;/code&gt;s directly load and store your data. Ever.

&lt;h4&gt;Moving child views to maintain the illusion&lt;/h4&gt;

&lt;p&gt;The trick in this post is handling an arbitrary array of child pages using just two views. It will work as follows:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Initially, the displayed view will be the &lt;code&gt;currentPage&lt;/code&gt; view. The next view will be configured to display the cached data for Page 1&lt;/li&gt;
&lt;li&gt;As the user begins scrolling to the right, the &lt;code&gt;nextPage&lt;/code&gt; is quickly moved into the location for the next page in the scrolling direction. At the same time as it is positioned, &lt;code&gt;nextPage&lt;/code&gt; is configured with the data for Page 2. Neither of these configuration changes will be visible to the user.&lt;/li&gt;
&lt;li&gt;As the scroll operation ends, the pointers for &lt;code&gt;currentPage&lt;/code&gt; and &lt;code&gt;nextPage&lt;/code&gt; are swapped so that &lt;code&gt;currentPage&lt;/code&gt; now points to the view displaying Page 2 and &lt;code&gt;nextPage&lt;/code&gt; now points to Page 1&lt;/li&gt;
&lt;li&gt;If the next scroll is to the left, &lt;code&gt;nextPage&lt;/code&gt; is already configured and in position. If the next scroll is to the right, &lt;code&gt;nextPage&lt;/code&gt; will be moved and configured as it was during the first scroll.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;The code that chooses how to move the views as the scroll view scrolls (step 2 in the above description) looks like this:&lt;/p&gt;

&lt;pre&gt;- (void)scrollViewDidScroll:(UIScrollView *)sender
{
    CGFloat pageWidth = scrollView.frame.size.width;
    float fractionalPage = scrollView.contentOffset.x / pageWidth;
    
    NSInteger lowerNumber = floor(fractionalPage);
    NSInteger upperNumber = lowerNumber + 1;
    
    if (lowerNumber == currentPage.pageIndex)
    {
        if (upperNumber != nextPage.pageIndex)
        {
            [self applyNewIndex:upperNumber pageController:nextPage];
        }
    }
    else if (upperNumber == currentPage.pageIndex)
    {
        if (lowerNumber != nextPage.pageIndex)
        {
            [self applyNewIndex:lowerNumber pageController:nextPage];
        }
    }&lt;/pre&gt;

&lt;p&gt;I've left off the final condition for size but it is a rarely invoked path for when very fast scrolling leaves the &lt;code&gt;currentPage&lt;/code&gt; out of position and it needs to configure both pages.&lt;/p&gt;

&lt;p&gt;The exchange of pointers at the end of scrolling (step 3 in the above description) is handled in the &lt;code&gt;scrollViewDidEndScrollingAnimation:&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)newScrollView
{
    CGFloat pageWidth = scrollView.frame.size.width;
    float fractionalPage = scrollView.contentOffset.x / pageWidth;
    NSInteger nearestNumber = lround(fractionalPage);

    if (currentPage.pageIndex != nearestNumber)
    {
        PageViewController *swapController = currentPage;
        currentPage = nextPage;
        nextPage = swapController;
    }

    pageControl.currentPage = currentPage.pageIndex;
}&lt;/pre&gt;

&lt;p&gt;The only remaining component to reveal is exactly how the pages are positioned and configured in &lt;code&gt;applyNewIndex:pageController:&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;- (void)applyNewIndex:(NSInteger)newIndex pageController:(PageViewController *)pageController
{
    NSInteger pageCount = [[DataSource sharedDataSource] numDataPages];
    BOOL outOfBounds = newIndex &gt;= pageCount || newIndex &lt; 0;

    if (!outOfBounds)
    {
        CGRect pageFrame = pageController.view.frame;
        pageFrame.origin.y = 0;
        pageFrame.origin.x = scrollView.frame.size.width * newIndex;
        pageController.view.frame = pageFrame;
    }
    else
    {
        CGRect pageFrame = pageController.view.frame;
        pageFrame.origin.y = scrollView.frame.size.height;
        pageController.view.frame = pageFrame;
    }

    pageController.pageIndex = newIndex;
}&lt;/pre&gt;


&lt;p&gt;You can see here that if a page is given an out-of-bounds index, it is placed below the bottom of the scroll view (invisible). I chose not to use &lt;code&gt;setHidden:&lt;/code&gt; on the view because this resulted in "pop-in" when making the view visible again.&lt;/p&gt;

&lt;p&gt;The actual configuration of the view for the new page index happens in the setter method for &lt;code&gt;pageController.pageIndex&lt;/code&gt;. This method fetches the data for the page out of the &lt;code&gt;DataSource&lt;/code&gt; and configures the view for displaying that page.&lt;/p&gt;

&lt;pre&gt;- (void)setPageIndex:(NSInteger)newPageIndex
{
    pageIndex = newPageIndex;
    
    if (pageIndex &gt;= 0 &amp;&amp;
        pageIndex &lt; [[DataSource sharedDataSource] numDataPages])
    {
        NSDictionary *pageData =
            [[DataSource sharedDataSource] dataForPage:pageIndex];
        label.text = [pageData objectForKey:@"pageName"];
        textView.text = [pageData objectForKey:@"pageText"];
    }
}&lt;/pre&gt;

&lt;p&gt;Notice that I've made this method tolerant of out-of-bounds indices. This is because while out-of-bounds indices are invalid for data from the &lt;code&gt;DataSource&lt;/code&gt;, they can be valid locations for views in the scroll view (representing an offscreen position) so these positions must be permitted.&lt;/p&gt;

&lt;h4&gt;Offscreen UITextViews don't update correctly&lt;/h4&gt;

&lt;p&gt;If you take a look at the &lt;a href="http://cocoawithlove.googlepages.com/PagingScrollView.zip"&gt;code for this sample project&lt;/a&gt;, you'll notice a method that I've added named &lt;code&gt;updateTextViews:&lt;/code&gt; and a value I track named &lt;code&gt;textViewNeedsUpdate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These parts of the program exist because &lt;code&gt;UITextView&lt;/code&gt; (used for the "Some text for Page X" display) don't update if they are offscreen (in this case: in an offscreen page of the &lt;code&gt;UIScrollView&lt;/code&gt;). This behavior isn't a problem when the &lt;code&gt;UITextView&lt;/code&gt; remains offscreen but becomes especially annoying when it is brought onscreen and still doesn't update.&lt;/p&gt;

&lt;p&gt;I have addressed this in 2 ways:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;When an update is applied, check if the &lt;code&gt;UITextView&lt;/code&gt; is offscreen. If it is, set &lt;code&gt;textViewNeedsUpdate&lt;/code&gt; to &lt;code&gt;YES&lt;/code&gt;. I check this value regularly during a scroll, to see if the &lt;code&gt;UITextView&lt;/code&gt; has appeared and update the view when it does.&lt;/li&gt;
&lt;li&gt;In some fast scrolling cases (mostly when using the &lt;code&gt;UIPageControl&lt;/code&gt; instead of the &lt;code&gt;UIScrollView&lt;/code&gt; to page) this still doesn't work &amp;mdash; so I always force one update to the &lt;code&gt;currentPage&lt;/code&gt; at the end of scrolling. This case can result in a visible update if your eyes are quick but it is an uncommon case.&lt;/li&gt;&lt;/ol&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can &lt;a href="http://cocoawithlove.googlepages.com/PagingScrollView.zip"&gt;download the complete Xcode 3.1 project for PagingScrollView&lt;/a&gt; (31kB).&lt;/blockquote&gt;

&lt;p&gt;It is possible to handle a paging scroll view using just 2 child views, no matter how many virtual pages you wish to support.&lt;/p&gt;

&lt;p&gt;This approach assumes the views can be reconfigured to display a new virtual page quickly (normally a safe assumption). Remember that the data displayed need not be fast to load for the pages to reconfigure quickly because the data is loaded and cached in a separate object, independent of the paging.&lt;/p&gt;

&lt;p&gt;The bug in &lt;code&gt;UITextView&lt;/code&gt; is annoying. I've presented a means of getting around it, although I'd be happy to see a better approach.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-804840528352435764?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/804840528352435764/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=804840528352435764" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/804840528352435764?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/804840528352435764?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html" title="Multiple virtual pages in a UIScrollView with just 2 child views" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0IFQn88cSp7ImA9WxVUE0k.&quot;"><id>tag:blogger.com,1999:blog-371408380585915800.post-5261135483404175696</id><published>2009-01-18T14:18:00.001-08:00</published><updated>2009-03-17T18:58:33.179-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-17T18:58:33.179-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AppKit" /><title>Demystifying NSApplication by recreating it</title><content type="html">&lt;span class="introduction"&gt;&lt;p&gt;In this post I will recreate code that is normally concealed between the &lt;code&gt;NSApplicationMain&lt;/code&gt; call (invoked in a Cocoa application's &lt;code&gt;main&lt;/code&gt; function) and the &lt;code&gt;sendEvent:&lt;/code&gt; method (which distributes the events to windows and views from the main run loop). By recreating this code for you, I hope to explain the steps that occur between program startup and the dispatch of events to your code &amp;mdash; so you can gain greater understanding of what &lt;code&gt;NSApplication&lt;/code&gt; does on your behalf.&lt;/p&gt;&lt;/span&gt;

&lt;span class="fullpost"&gt;
&lt;h4&gt;Introduction&lt;/h4&gt;
&lt;p&gt;The default Cocoa Application template provided by Xcode contains just one line of code, in one function:&lt;/p&gt;

&lt;pre&gt;int main(int argc, char *argv[])
{
    return NSApplicationMain(argc,  (const char **) argv);
}&lt;/pre&gt;

&lt;p&gt;Somehow, this one line of code is enough to create a menubar, put a window onscreen and then handle user events (mouse clicks and menu selections) until the user quits the program, at which point the application gracefully exits.&lt;/p&gt;

&lt;h4&gt;What we know&lt;/h4&gt;

&lt;p&gt;Scattered throughout the Cocoa documentation are hints about what must happen in &lt;code&gt;NSApplicationMain&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read from the "Info.plist" file to determine:
&lt;ul&gt;&lt;li&gt;The name of the "MainMenu" NIB file to load automatically on startup&lt;/li&gt;
&lt;li&gt;The name of the application's principal class (the class of the application object)&lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Construct the application object&lt;/li&gt;
&lt;li&gt;Load the "MainMenu" NIB file&lt;/li&gt;
&lt;li&gt;Begin the "Run Loop" (which handles the rest of the program)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;I will recreate all of these steps by implementing my own version of &lt;code&gt;NSApplicationMain&lt;/code&gt; &amp;mdash; named &lt;code&gt;MyApplicationMain&lt;/code&gt; &amp;mdash; and by creating my own &lt;code&gt;NSApplication&lt;/code&gt; subclass that implements the &lt;code&gt;run&lt;/code&gt; method for itself.&lt;/p&gt;

&lt;h4&gt;MyApplicationMain&lt;/h4&gt;

&lt;h5&gt;Create the application object&lt;/h5&gt;

&lt;p&gt;The first step in the &lt;code&gt;MyApplicationMain&lt;/code&gt; function is to read the name of the "Principal class" and construct the application object from this class.&lt;/p&gt;

&lt;pre&gt;NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
Class principalClass =
    NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]);
NSAssert([principalClass respondsToSelector:@selector(sharedApplication)],
    @"Principal class must implement sharedApplication.");
NSApplication *applicationObject = [principalClass sharedApplication];&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;infoDictionary&lt;/code&gt; method returns the "Info.plist" for a bundle (in this case, our application's bundle) converted into an &lt;code&gt;NSDictionary&lt;/code&gt; for easy access. All we need to do is get the "NSPrincipalClass" string and fetch the class identified by that string.&lt;/p&gt;

&lt;p&gt;Since the application is a singleton, we construct it by calling the &lt;code&gt;sharedApplication&lt;/code&gt; method on the class. If we try to construct the object using standard &lt;code&gt;alloc&lt;/code&gt; and &lt;code&gt;init&lt;/code&gt; calls, the &lt;code&gt;NSApp&lt;/code&gt; singleton instance won't be set correctly and an exception will be thrown at a later point when a second application is created.&lt;/p&gt;

&lt;blockquote&gt;For more information on singletons, you can see &lt;a href="http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html"&gt;my earlier post about singletons&lt;/a&gt; or visit Apple's page on &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/chapter_3_section_10.html"&gt;Creating a Singleton Instance&lt;/a&gt;.&lt;/blockquote&gt; 

&lt;h5&gt;Load the contents of the MainMenu NIB file&lt;/h5&gt;

&lt;p&gt;Loading the "MainMenu" NIB file is a similar task: get the name from the &lt;code&gt;infoDictionary&lt;/code&gt; and then load it.&lt;/p&gt;

&lt;pre&gt;NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
NSNib *mainNib =
    [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]];
[mainNib instantiateNibWithOwner:applicationObject topLevelObjects:nil];&lt;/pre&gt;

&lt;p&gt;I briefly considered implementing the &lt;code&gt;NSNib&lt;/code&gt; code too, to show how that works for loading objects in a NIB file, but since the format of a NIB file is not publicly declared, it wasn't possible. Suffice it to say that the &lt;code&gt;instantiateNibWithOwner:topLevelObjects&lt;/code&gt; method performs the following steps:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Allocates all the objects in the NIB file and initializes them with one of the following methods:
&lt;ul&gt;&lt;li&gt;&lt;code&gt;initWithFrame:&lt;/code&gt; (used for &lt;code&gt;NSView&lt;/code&gt; objects)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;initWithCoder:&lt;/code&gt; (used for most other objects in the Interface Builder library)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;init&lt;/code&gt; (used for all other objects)&lt;/li&gt;&lt;/ul&gt;
&lt;li&gt;Sets the &lt;code&gt;IBOutlet&lt;/code&gt; pointers on objects as specified in the NIB file and establishes all bindings&lt;/li&gt;
&lt;li&gt;Invokes &lt;code&gt;awakeFromNib&lt;/code&gt; on all objects that implement this method&lt;/li&gt;&lt;/ul&gt;

&lt;h5&gt;Start the run loop&lt;/h5&gt;

&lt;p&gt;It is extremely important that the application's main loop runs on the main thread. For this reason, we don't directly invoke &lt;code&gt;run&lt;/code&gt; but instead make sure it is performed on the main thread.&lt;/p&gt;

&lt;pre&gt;if ([applicationObject respondsToSelector:@selector(run)])
{
    [applicationObject
        performSelectorOnMainThread:@selector(run)
        withObject:nil
        waitUntilDone:YES];
}&lt;/pre&gt;

&lt;p&gt;I also check that the &lt;code&gt;applicationObject&lt;/code&gt; will respond to the method before trying to invoke it, just in case the "Principal Class" from the Info.plist file is not a valid &lt;code&gt;NSApplication&lt;/code&gt; or &lt;code&gt;NSApplication&lt;/code&gt;-like object.&lt;/p&gt;

&lt;h4&gt;Implementing our own run loop&lt;/h4&gt;

&lt;p&gt;The remaining task required so that you can trace the application's execution from startup to dispatch of events to your code is the implementation of the run loop.&lt;/p&gt;

&lt;p&gt;Despite Apple's comment in the &lt;code&gt;NSApplication&lt;/code&gt; documentation that &lt;code&gt;run&lt;/code&gt; is one of the "Methods to Override", my brief search failed to uncover anyone who had actually done it. My suspicion is this: it is &lt;em&gt;not&lt;/em&gt; a method to override and that document is woefully out-of-date. The only reason to implement your own &lt;em&gt;run&lt;/em&gt; method now is curiosity, not functionality.&lt;/p&gt;

&lt;p&gt;In that spirit, here's a reimplementation of &lt;code&gt;run&lt;/code&gt; and a corresponding &lt;code&gt;terminate&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;- (void)run
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self finishLaunching];

    shouldKeepRunning = YES;
    do
    {
        [pool release];
        pool = [[NSAutoreleasePool alloc] init];

        NSEvent *event =
            [self
                nextEventMatchingMask:NSAnyEventMask
                untilDate:[NSDate distantFuture]
                inMode:NSDefaultRunLoopMode
                dequeue:YES];

        [self sendEvent:event];
        [self updateWindows];
    } while (shouldKeepRunning);

    [pool release];
}

- (void)terminate:(id)sender
{
    shouldKeepRunning = NO;
}&lt;/pre&gt;

&lt;p&gt;It's as simple as you might expect: take the next event out of the queue for your application and route it appropriately using &lt;code&gt;sendEvent:&lt;/code&gt; which handles the task of determining which window wants the event and invokes &lt;code&gt;sendEvent:&lt;/code&gt; on the window to further route the event to a specific view.&lt;/p&gt;

&lt;p&gt;For those interested: I discovered all the methods that need to be invoked in the &lt;code&gt;run&lt;/code&gt; method in the most naive way: by searching the &lt;code&gt;NSApplication&lt;/code&gt; documentation for "loop" to find all methods that claimed they were invoked in the main run loop.&lt;/p&gt;

&lt;p&gt;The specific function of &lt;code&gt;finishLaunching&lt;/code&gt; method is a bit of a mystery. All I know is that menus, menu updates and a host of other features won't work if it isn't invoked. It is possible that it sets up the responder chain for some actions. It is possible it adds observers to the run loop. I don't really know.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nextEventMatchingMask:untilDate:inMode:dequeue:&lt;/code&gt; is the biggest reason why I chose, when "reimplementing" &lt;code&gt;NSApplication&lt;/code&gt; for this post, to make my implementation a subclass of &lt;code&gt;NSApplication&lt;/code&gt; instead of a completely separate class. This method (or something it contains) converts notifications from the operating system and hardware drivers into &lt;code&gt;NSEvent&lt;/code&gt; objects. A principal class is not required to be a subclass of &lt;code&gt;NSApplication&lt;/code&gt; but I wouldn't know where to begin reimplementing this method, so I had to use &lt;code&gt;NSApplication&lt;/code&gt; to do it.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;blockquote&gt;You can download an implementation of the default Cocoa Application Xcode 3.1 project that uses this code: &lt;a href="http://cocoawithlove.googlepages.com/RecreatingNSApplication.zip"&gt;RecreatingNSApplication.zip&lt;/a&gt; (60kB)&lt;/blockquote&gt;

&lt;p&gt;This recreation of &lt;code&gt;NSApplicationMain&lt;/code&gt; and &lt;code&gt;NSApplication&lt;/code&gt;'s &lt;code&gt;run&lt;/code&gt; does not do everything that the real implementations do (I've deliberately kept it simple for clarity) but I think it shows that the key steps involved are straightforward and easy to understand.&lt;/p&gt;

&lt;p&gt;There are a few steps that I haven't reimplemented: loading NIB files, retrieving events and routing events. Unfortunately, these remain black boxes to me, so I can't shed further light on them. You can find out some things by setting breakpoints (in your constructors for objects created in NIBs or in your event methods) and reading the names of Apple functions invoked to bring these commands to you.&lt;/p&gt;

&lt;p&gt;Beyond this, you can also read how &lt;a href="http://www.koders.com/objectivec/fidC548A9896F2887D86D7074E7C563CC920B1698EC.aspx"&gt;GNUStep implements the same methods&lt;/a&gt;. Apple doesn't necessarily do the same thing but GNUStep at least represents an observable solution to the same problems.&lt;/p&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/371408380585915800-5261135483404175696?l=cocoawithlove.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://cocoawithlove.com/feeds/5261135483404175696/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=371408380585915800&amp;postID=5261135483404175696" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5261135483404175696?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/371408380585915800/posts/default/5261135483404175696?v=2" /><link rel="alternate" type="text/html" href="http://cocoawithlove.com/2009/01/demystifying-nsapplication-by.html" title="Demystifying NSApplication by recreating it" /><author><name>Matt Gallagher</name><uri>http://www.blogger.com/profile/12617910364694969282</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="14290033605020307432" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
