<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Fri, 24 Feb 2012 09:18:48 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Jordan Breeding's Blog</title><link>http://www.jordanbreeding.com/blog/</link><description></description><lastBuildDate>Wed, 13 Jul 2011 08:09:47 +0000</lastBuildDate><copyright></copyright><language>en-US</language><generator>Squarespace Site Server v5.11.81 (http://www.squarespace.com/)</generator><item><title>Another Big Change</title><dc:creator>Jordan Breeding</dc:creator><pubDate>Wed, 13 Jul 2011 08:06:31 +0000</pubDate><link>http://www.jordanbreeding.com/blog/2011/7/13/another-big-change.html</link><guid isPermaLink="false">393790:4278260:12102898</guid><description><![CDATA[<p>On July 18th I will be leaving to move Plano, TX to move to Campbell, CA. While in California I will be working for Apple Inc. What this means for this blog and my writing is two things:</p>
<p><ol>
<li>I might actually stand a chance of having some free time to write again.</li>
<li>That writing will no longer be of a technical nature, regardless of where it is posted.</li>
</ol></p>
<p>This is a huge change for me, I've been in Texas (and more specifically the Dallas area) my entire life. I'm very exited to start my new job and see what the future holds. See you on the flip side.</p>]]></description><wfw:commentRss>http://www.jordanbreeding.com/blog/rss-comments-entry-12102898.xml</wfw:commentRss></item><item><title>Change of Pace</title><dc:creator>Jordan Breeding</dc:creator><pubDate>Thu, 13 Jan 2011 08:33:58 +0000</pubDate><link>http://www.jordanbreeding.com/blog/2011/1/13/change-of-pace.html</link><guid isPermaLink="false">393790:4278260:10022787</guid><description><![CDATA[<p>Well, it has been quite some time since I posted anything here. I have been quite busy since April, and I'd like to take an opportunity to cover some of what has happened since then.</p>
<p>First, however, I would like to state that I do intended to state posting more regular updates to this blog.</p>
<p>In June I accepted a position working on iOS development full-time for Rockfish Interactive. This was quite fulfilling and I enjoyed meeting and working with some very talented people. At the same time I also continued improving my skills on my own time and also working on some side projects.</p>
<p>In late September this effort paid off in a big way when I accepted an offer to go to work at Zarra Studios with Marcus and his team starting October 15th. Since that time I have been caught up in a whirlwind of working on amazing projects with amazing people and loving every minute of it.</p>
<p>Because of the fact that I now work for Marcus and Zarra Studios I am making changes around here. Effective immediately this blog will for the foreseeable future target personal posts and shorter technical posts. The longer articles I have been working on and any other technical content non-trivial length will now be worked up and posted to <a href="http://cimgf.com">Cocoa Is My Girlfriend</a>.</p>
<p>I realize that I don't have many followers, but I believe that posting future technical content to <a href="http://cimgf.com">Cocoa Is My Girlfriend</a> will serve both my limited audience and myself better than posting things here would.</p>
<p> Thanks for sticking around this long if you have. I look forward to getting out some new content in the near future.</p>]]></description><wfw:commentRss>http://www.jordanbreeding.com/blog/rss-comments-entry-10022787.xml</wfw:commentRss></item><item><title>Introducing Continuations for Objective-C</title><category>blocks</category><category>continuations</category><category>obj-c</category><dc:creator>Jordan Breeding</dc:creator><pubDate>Thu, 08 Apr 2010 04:23:49 +0000</pubDate><link>http://www.jordanbreeding.com/blog/2010/4/7/introducing-continuations-for-objective-c.html</link><guid isPermaLink="false">393790:4278260:7263792</guid><description><![CDATA[<p>On February 5 Mike Ash <a href="http://mikeash.com/pyblog/friday-qa-2010-02-05-error-returns-with-continuation-passing-style.html">wrote about continuations in Objective-C</a>. I immediately liked the style of continuations (from Mike's article) based on two separate blocks, but I had the same concern as Mike: "obviously the annoyance of having to write adapters makes for a big hit to the niceness of using CPS for error handling."<br /> <br /> In response I came up with a crude version of automated continuations for Objective-C. About one month, several email exchanges with Mike, and a lot of <span style="font: monospace; background-color: #dddddd;">NSProxy</span> usage later, I ended up with a new framework that handles several different styles of automatic continuations in Objective-C.<br /> <br /> If you are interested in the technical details of what's going on behind the scenes please see <a href="http://github.com/jordanbreeding/JBBContinuations">my project on GitHub</a>, especially the following files:</p>
<ul>
<li><a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Classes/JBBObjectProxy.h">Classes/JBBObjectProxy.h</a></li>
<li><a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Classes/JBBObjectProxy.m">Classes/JBBObjectProxy.m</a></li>
<li><a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Classes/Extensions/NSInvocation+JBBContinuations.h">Classes/Extensions/NSInvocation+JBBContinuations.h</a></li>
<li><a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Classes/Extensions/NSInvocation+JBBContinuations.m">Classes/Extensions/NSInvocation+JBBContinuations.m</a></li>
<li><a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Classes/Extensions/NSObject+JBBContinuations.h">Classes/Extensions/NSObject+JBBContinuation.h</a></li>
<li><a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Classes/Extensions/NSObject+JBBContinuations.m">Classes/Extensions/NSObject+JBBContinuation.m</a></li>
</ul>
<p>The key to making all of this work is ensuring that continuation blocks always recieve an object. To achieve this I pass objects straight through the proxy and wrap everything else in an <span style="font: monospace; background-color: #dddddd;">NSValue</span> (with type encoding specified).<br /> <br /> If you call <span style="font: monospace; background-color: #dddddd;">+[JBBObjectProxy getStoredInvocation]</span> directly instead of using the <span style="font: monospace; background-color: #dddddd;">WRAP_MSG_SEND()</span> macro, the call must be from the same thread that messaged the proxy. If you need to invoke the <span style="font: monospace; background-color: #dddddd;">NSInvocation</span> on a separate thread you should still call <span style="font: monospace; background-color: #dddddd;">+[JBBObjectProxy getStoredInvocation]</span> on the original thread, then pass the returned <span style="font: monospace; background-color: #dddddd;">NSInvocation</span> instance to the other thread.<br /> <br /> The following are basic samples demonstrating how to use JBBContinuations:</p>
<ol>
<li>Do not use continuations (provided for comparison). (<a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Examples/Reference%20Counted/test_1.m">This sample on GitHub</a>)
<pre style="background-color: #dddddd;">#import &lt;Cocoa/Cocoa.h&gt;
#import &lt;JBBContinuations/JBBContinuations.h&gt;

int main(int argc, char *argv[]) {
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];

    NSError *anError = nil;
    NSString *aString = nil;
    NSString *anotherString = nil;

    aString = [NSString
               stringWithCString:"this is a test"
                        encoding:NSUTF8StringEncoding];
    NSLog(@"%@", aString);

    anotherString = [NSString
                     stringWithCString:"this is another test"
                              encoding:NSUTF8StringEncoding];
    NSLog(@"%@", anotherString);

    if (![NSString
          stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                          encoding:NSUTF8StringEncoding
                             error:&amp;anError]) {
        if (anError) {
            NSLog(@"an error occurred: %@", anError);
        } else {
            NSLog(@"an error occurred");
        }
    } else {
        NSLog(@"no error occurred");
    }

    [localPool drain];
    return 0;
}
</pre>
</li>
<li>Create an empty proxy; message it directly. The proxy automatically passes through return values. (<a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Examples/Reference%20Counted/test_1a.m">This sample on GitHub</a>)
<pre style="background-color: #dddddd;">#import &lt;Cocoa/Cocoa.h&gt;
#import &lt;JBBContinuations/JBBContinuations.h&gt;

int main(int argc, char *argv[]) {
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];

    NSError *anError = nil;
    NSString *aString = nil;
    NSString *anotherString = nil;

    aString = [[NSString jbb_proxy]
               stringWithCString:"this is a test"
                        encoding:NSUTF8StringEncoding];
    NSLog(@"%@", aString);

    anotherString = [[NSString jbb_proxy]
                     stringWithCString:"this is another test"
                              encoding:NSUTF8StringEncoding];
    NSLog(@"%@", anotherString);

    if (![[NSString jbb_proxy]
          stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                          encoding:NSUTF8StringEncoding
                             error:&amp;anError]) {
        if (anError) {
            NSLog(@"an error occurred: %@", anError);
        } else {
            NSLog(@"an error occurred");
        }
    } else {
        NSLog(@"no error occurred");
    }

    [localPool drain];
    return 0;
}
</pre>
</li>
<li>Create an empty proxy; message it directly; use +[JBBObjectProxy getStoredInvocation]; invoke the NSInvocation with continuations and error handlers. Optionally you may use the WRAP_MSG_SEND() macro. (<a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Examples/Reference%20Counted/test_2.m">This sample on GitHub</a>)
<pre style="background-color: #dddddd;">#define WRAP_MSG_SEND(anObject, ...) \
        ([[anObject jbb_proxy] __VA_ARGS__], \
         [JBBObjectProxy getStoredInvocation])
</pre>
<pre style="background-color: #dddddd;">#import &lt;Cocoa/Cocoa.h&gt;
#import &lt;JBBContinuations/JBBContinuations.h&gt;

int main(int argc, char *argv[]) {
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];

    [WRAP_MSG_SEND(NSString,
             stringWithCString:"this is a test"
                      encoding:NSUTF8StringEncoding)
     jbb_invokeWithContinuation:^(id anObject) {
        NSLog(@"%@", anObject);
    }];

    __block NSString *anOutsideObject = nil;
    [WRAP_MSG_SEND(NSString,
              stringWithCString:"this is another test"
                       encoding:NSUTF8StringEncoding)
     jbb_invokeWithContinuation:^(id anObject) {
        anOutsideObject = [anObject retain];
    }];
    NSLog(@"%@", [anOutsideObject autorelease]);

    [WRAP_MSG_SEND(NSString,
       stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                       encoding:NSUTF8StringEncoding
                          error:nil)
     jbb_invokeWithContinuation:^(id anObject) {
        NSLog(@"no error occurred");
    }
                   errorHandler:^(NSError *anError) {
        if (anError) {
            NSLog(@"an error occurred: %@", anError);
        } else {
            NSLog(@"an error occurred");
        }
    }];

    [localPool drain];
    return 0;
}
</pre>
</li>
<li>Create an empty proxy; message it with continuations and error handlers attached. (<a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Examples/Reference%20Counted/test_3.m">This sample on GitHub</a>)
<pre style="background-color: #dddddd;">#import &lt;Cocoa/Cocoa.h&gt;
#import &lt;JBBContinuations/JBBContinuations.h&gt;

int main(int argc, char *argv[]) {
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];

    [[NSString jbb_proxy]
      stringWithCString:"this is a test"
               encoding:NSUTF8StringEncoding
           continuation:^(id anObject) {
        NSLog(@"%@", anObject);
    }];

    __block NSString *anOutsideObject = nil;
    [[NSString jbb_proxy]
     stringWithCString:"this is another test"
              encoding:NSUTF8StringEncoding
          continuation:^(id anObject) {
        anOutsideObject = [anObject retain];
    }];
    NSLog(@"%@", [anOutsideObject autorelease]);

    [[NSString jbb_proxy]
     stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                     encoding:NSUTF8StringEncoding
                        error:nil
                 continuation:^(id anObject) {
        NSLog(@"no error occurred");
    }
                 errorHandler:^(NSError *anError) {
        if (anError) {
            NSLog(@"an error occurred: %@", anError);
        } else {
            NSLog(@"an error occurred");
        }
    }];

    [localPool drain];
    return 0;
}
</pre>
</li>
<li>Create a proxy with an associated continuation and error handler; message it directly. (<a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Examples/Reference%20Counted/test_4.m">This sample on GitHub</a>)
<pre style="background-color: #dddddd;">#import &lt;Cocoa/Cocoa.h&gt;
#import &lt;JBBContinuations/JBBContinuations.h&gt;

int main(int argc, char *argv[]) {
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];

    [[NSString jbb_proxyWithContinuation:^(id anObject) {
        NSLog(@"%@", anObject);
    }] stringWithCString:"this is a test"
                encoding:NSUTF8StringEncoding];

    __block NSString *anOutsideObject = nil;
    [[NSString jbb_proxyWithContinuation:^(id anObject) {
        anOutsideObject = [anObject retain];
    }] stringWithCString:"this is another test"
                encoding:NSUTF8StringEncoding];
    NSLog(@"%@", [anOutsideObject autorelease]);

    [[NSString jbb_proxyWithContinuation:^(id anObject) {
        NSLog(@"no error occurred");
    }
                            errorHandler:^(NSError *anError) {
        if (anError) {
            NSLog(@"an error occurred: %@", anError);
        } else {
            NSLog(@"an error occurred");
        }
    }] stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                       encoding:NSUTF8StringEncoding error:nil];

    [localPool drain];
    return 0;
}
</pre>
</li>
<li>Create a proxy with an associated continuation and error handler; message it with overriding continuations and error handlers attached. (<a href="http://github.com/jordanbreeding/JBBContinuations/blob/master/Examples/Reference%20Counted/test_5.m">This sample on GitHub</a>)
<pre style="background-color: #dddddd;">#import &lt;Cocoa/Cocoa.h&gt;
#import &lt;JBBContinuations/JBBContinuations.h&gt;

int main(int argc, char *argv[]) {
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];

    id baseProxy = [NSString
                    jbb_proxyWithContinuation:^(id anObject) {
                       NSLog(@"base continuations");
                   }
                                 errorHandler:^(NSError *anError) {
                       NSLog(@"base errorHandler");
                   }];

    [baseProxy
     stringWithCString:"this is a test"
              encoding:NSUTF8StringEncoding];

    [baseProxy
     stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                      encoding:NSUTF8StringEncoding error:nil];

    [baseProxy
     stringWithCString:"this is a test"
              encoding:NSUTF8StringEncoding
          continuation:^(id anObject) {
        NSLog(@"%@", anObject);
    }];

    __block NSString *anOutsideObject = nil;
    [baseProxy
     stringWithCString:"this is another test"
              encoding:NSUTF8StringEncoding
          continuation:^(id anObject) {
        anOutsideObject = [anObject retain];
    }];
    NSLog(@"%@", [anOutsideObject autorelease]);

    [baseProxy
     stringWithContentsOfFile:@"/tmp/completely_fake_file.txt"
                     encoding:NSUTF8StringEncoding error:nil
                 continuation:^(id anObject) {
        NSLog(@"no error occurred");
    }
                 errorHandler:^(NSError *anError) {
        if (anError) {
            NSLog(@"an error occurred: %@", anError);
        } else {
            NSLog(@"an error occurred");
        }
    }];

    [localPool drain];
    return 0;
}
</pre>
</li>
</ol>
<p>Style no. 2 is equivalent to a straight message send (except that it caches the invocation in case you ask for it later). No. 3 is the most like traditional Objective-C message sending without being dangerous. No. 5 is useful when you use the same continuations multiple times. Styles no. 4 and 6 are the most dangerous because the fake selectors are not known in any header files (the compiler assumes <span style="font: monospace; background-color: #dddddd;">id</span> is the return type), but their syntax is almost identical to straight message sends. For safety I ensure an <span style="font: monospace; background-color: #dddddd;">id</span> is returned (wrapping non-object values in <span style="font: monospace; background-color: #dddddd;">NSValue</span>); however, the compiler warnings from the unknown selectors render <span style="font: monospace; background-color: #dddddd;">-Werror</span> useless.<br /> <br /> In less than two months, I created a system for automatically using continuations with Objective-C. This system is useable and works in Snow Leopard without modifications of any kind. It is also likely to work under Leopard or iPhone OS using <a href="http://code.google.com/p/plblocks/">PLBlocks</a>.</p>]]></description><wfw:commentRss>http://www.jordanbreeding.com/blog/rss-comments-entry-7263792.xml</wfw:commentRss></item><item><title>10.6.2: CFBinaryHeap's CopyDescription Still Broken</title><dc:creator>Jordan Breeding</dc:creator><pubDate>Fri, 13 Nov 2009 05:41:10 +0000</pubDate><link>http://www.jordanbreeding.com/blog/2009/11/12/1062-cfbinaryheaps-copydescription-still-broken.html</link><guid isPermaLink="false">393790:4278260:5784203</guid><description><![CDATA[<p>So, 10.6.2 came out recently and unfortunately CFBinaryHeap is still broken. In CFBinaryHeap you can provide a callback .copyDescription in the struct you use to initialize things. When you then do a CFShow() or a CFCopyDescription() on the CFBinaryHeap instance it should automatically print its own info, and also the info for each item in the heap.</p>
<p>Unfortunately as of 10.6.2 CoreFoundation still has a problem in that the CFBinaryHeap is using "%s" to print the string even though it is a CFStringRef and not a char*.</p>
<p>Hopefully at some point this will get fixed since it would be nice to not have to manually iterate over a CFBinaryHeap to print it out. Thanks go to Dave Dribin for helping me track the problem down to CoreFoundation itself. A radar has been on file since shortly after 10.6.0.</p>]]></description><wfw:commentRss>http://www.jordanbreeding.com/blog/rss-comments-entry-5784203.xml</wfw:commentRss></item><item><title>Just a Quick Note</title><dc:creator>Jordan Breeding</dc:creator><pubDate>Fri, 10 Jul 2009 14:54:42 +0000</pubDate><link>http://www.jordanbreeding.com/blog/2009/7/10/just-a-quick-note.html</link><guid isPermaLink="false">393790:4278260:4583126</guid><description><![CDATA[<p>My blog will be moving here shortly from its current Tumblr location.</p>]]></description><wfw:commentRss>http://www.jordanbreeding.com/blog/rss-comments-entry-4583126.xml</wfw:commentRss></item></channel></rss>
