On indie iOS and Mac development.

Archive for the ‘Software Development’ Category

My Thoughts on RubyMotion

Monday, May 7th, 2012

RubyMotion was announced this past week. In my world view, creation is better than talk, and there is no doubt that the developers of RubyMotion should be congratulated for shipping something. That’s more than a lot of people do and is worthy of great respect.

That said, my initial reaction was less than enthusiastic and received a fair amount of push back from my Twitter followers. To summarize my opinion, I feel that although it’s an admirable effort, and worthy of congratulations, I simply cannot recommend to new developers coming to the platform that they use a technology such as RubyMotion to build apps for iOS.

Sadly, 140 chars is simply not enough to lay out my reasons for this opinion, so instead, I thought I’d save up my thoughts and lay them out in a blog post. If you are a fan of RubyMotion, or MacRuby, then I’ll save you the effort of reading: Use them if they work for you, but in my opinion, it would be less effort to simply learn Objective-C.

What is RubyMotion

RubyMotion is a toolchain which enables you to write apps for iOS using Ruby. The toolchain interfaces directly with Cocoa Touch, so you still use the same Cocoa Touch API, but you use it through Ruby. Apps are created on the command line, and developers may, in fact are encouraged to, avoid Xcode altogether. RubyMotion is built on MacRuby, which, unlike the long-since-retired Java/Objective-C bridge uses the same runtime as Objective-C, so it has the advantage of always having access to the latest library APIs as soon as they ship. There is no need for the MacRuby distribution to track OS updates in lock-step motion.

So if you’re a Ruby developer who doesn’t know Objective-C, then this is great, because you get to program for the latest, hottest platform without having to deal with all that messy, icky Objective-C stuff.

Well, almost…

Keeping up to date

My experience in the past with technologies like RubyMotion is that they have difficulty staying up to date. When I pointed this out on Twitter, several people took issue with this assertion, rightfully claiming “But it’ll always be up to date with whatever the frameworks give you!” To which I say, “That’s not the stuff I’m worried about being up to date with!”

Ruby is a moving target

First, Ruby itself is a moving target, and Mac OS X doesn’t always ship with the latest greatest stuff. So this means you’re going to be always compiling and upgrading Ruby every time you update your OS. I have never seen a community so fond of deprecation as the Ruby community seems to be. Granted, tools like rvm and the like make this job a bit easier, but it is an additional level of complexity that can be a hassle.

Objective-C is a moving target

The bigger issue, I think, however, is that Objective-C is an actively growing language. Not just at the framework level, which is what most of the RubyMotion fans point to when they talk about compatibility, but also at the lower syntax level. Blocks, for example, are a very recent addition to the language.

RubyMotion can’t help but fall a bit behind when low level features like blocks are added to the Objective-C language. Although it’s easy to criticize Objective-C and talk about how it’s only adding features Ruby has had for years, that’s irrelevant. The point is that supporting new language features like this will always take effort and modifications to RubyMotion. Since Apple has (presumably) more engineers working on improving Objective-C than RubyMotion has on improving RubyMotion, that means that RubyMotion will always be slower to adopt new language features than Objective-C is in adding them.

Debugging and tools

I’ve written full apps using PyObjC and other technologies similar to RubyMotion. When I did, I inevitably reached a point where my frustration would get the better of me. Surprisingly, it was usually a result of having to debug the code I’d written in Python or Ruby.

Say what you will about gdb and lldb, they are still both lightyears ahead of their ruby equivilents. The same goes for the profiling tools that Apple provides. Scripting language advocates like to promote the idea that although their languages may be slower than compiled code, you can always redo slow portions of your code in C, C++, or in our case, Objective-C. The problem, however, is the tools to find out what portion of your code is slow are absolutely horrendous. Compare them to Instruments, which is a spectacular profiling tool by any measure, and you’ll see what I mean.

Xcode has its detractors, the RubyMotion developers among them, but whether you like Xcode or not, it is the designated tool that Apple has blessed for doing iOS development. Apple invests a substantial amount of R&D in this tool, and it’s ridiculous to think that it’s going to stay where it is. In fact, I would expect some of the upcoming improvements to iOS development to come in the form of more GUI oriented tools. A recent example of this is the introduction of StoryBoards. Imagine when tools like this become available!

Now, it’s fine and dandy if you’re a neckbeard and you eschew all GUI tools in favor of your l33ta55 vi/emacs skillz. I totally appreciate how amazingly productive you are with your hotkeys that let you do everything without moving your hands from the keyboard. I’m sure you’ll have a wonderful old age with your fingers curled and umoving thanks to RSI. What you don’t realize is that having a variety of movements (ie: going back and forth to the mouse occaisionally) while slower, is actually a healthier way to work. I know this because I was once you. I used to use emacs for everything, and command line for everything. And I had the wrist pain to prove it. Since I switched to Xcode and using more GUI tools, my wrist pain has totally disappeared.

Regardless of that, however, the key takeaway here is that overall, the tools provided by Apple are the best for what they do, will continue to improve, and may even, in the future, negate whatever perceived improvement you’re getting from using a higher level language. In fact, I’d go so far as to say that, Xcode aside, even Instruments, llvm, and lldb provide enough value today to make the gains you get from a higher level language irrelevant.

Not having to learn Objective-C

Finally, the big one.

I’m going to put this in bold here so it stands out and you remember it. It may be the most important part of this blog post. Here it is:

If you think that using RubyMotion is going to make it so you don’t need to learn Objective-C… you are wrong.

Remember up above where I said that RubyMotion uses the same runtime and Cocoa Touch API as Objective-C? Well guess what that means?

That means that the vast majority of the difficulty in learning to program for iOS, that is, learning the Cocoa Touch API, is still gonna be there for you… but now, thanks to the fact that you’re using a non-standard language to do it, you won’t be able to directly use any of the huge amounts of already existing sample code, courses, or reading material available across the Internet.

Instead, you’ll need to learn the ins and outs of Objective-C just to translate those examples into something you can use and then figure out how to use it from Ruby, because, it’s not gonna feel like straight up Ruby. It’s gonna feel like some weird amalgamation.

In fact, you’ll probably need to know Objective-C and the Cocoa Touch API better than a newbie Objective-C programmer, because you really will need to understand the code. Newbie Objective-C coders can probably get by just cutting and pasting, but you’ll need to translate it.

That’s harder than you might think.

Conclusion

So the point here is that the benefits of using a language and toolset other than Objective-C for iOS development simply are not there.

Please don’t get me wrong, I love Ruby, I love Python, I’ve written thousands of lines of code in them. In fact, my affair with Ruby started before I’d even heard of Objective-C! I started using Ruby in 2000. Yes, before Rails even. (Yeah, that’s right, I’m hip like that. @@ ) I think Ruby has it’s place, but iOS development isn’t it. Objective-C, Xcode, and Instruments are the right tools for that job. Similarly, Java is the right tool for Android. C# for Windows. Ruby or Python for server side scripting and automation. I think this is the only truly objective view that one can have.

My advice to new developers who want to write for iOS and who are on the fence about RubyMotion? In my opinion, don’t use it. Objective-C isn’t really that hard, and the fact that you already know a language (Ruby) will only make it easier. Saying you don’t like Objective-C based on superficial issues like brackets is simply xenophobia. You’re smart, you’ll get used to it.

Leaking ARC Memory on an NSURLConnection Wrapper?

Wednesday, October 12th, 2011

Wherein I document a case of my ignorance in the hopes you can avoid going down the same rat hole. This is a bit long and rambling, my apologies for that.


As you may know, gentle reader… I have decided to go full steam ahead to converting my apps to ARC.. It’s been a fun process… with it’s own share of complexities, but overall, not too bad. My first converted app, Wasabi, was fairly easy. However, there are a few design patterns I tend to use in my code which skirt the rules of prudence when writing manual retain and release Objective-C, so I was a bit concerned how ARC would handle them. To some, the solutions may be obvious, but they weren’t at all obvious to me, so I’m documenting them here, in case someone else should run into a similar issue. In this case, the issue turned out not to be anything to do with ARC at all, but my tracking it down was educational nonetheless, and useful, I suppose, to talk about.

So, without further ado, I offer you the following manual retain and release Objective-C code:

- (IBAction)buttonPushed:(id)sender 
{
    NSURLRequest *req = [NSURLRequest requestWithURL:
            [NSURL URLWithString:@"http://ax.phobos.apple.com.
                  edgesuite.net/WebObjects/MZStoreServices.woa/
                  wa/wsSearch?term=zen"]];

    JSONWebCommand *command = [[JSONWebCommand alloc] 
                  initWithRequest:req];

    command.completionBlock = ^(NSDictionary *result)
    {
        NSLog(@"Complete. Result: %@", result);
    };

    command.finallyBlock = ^
    { 
        NSLog(@"Finished"); 
        [command release];
    };

    NSLog(@"Starting load...");

    [command start];
}

So, in this code… there’s this JSONWebCommand class, whose purpose is to wrap an NSURLConnection and make it simpler to use and give it some block capabilities. Basically, no need to implement delegate callbacks and things, you just give it blocks instead of a delegate, and it automagically parses the resultant response from JSON to an NSDictionary. Everything is nice and clean. The finallyBlock is always called, regardless of whether the command completes successfully or not. So I used this in the past, as shown here, to release my command ([command release]).

This way I could make this call be very fire and forget. That is, I fire off this command, and I forget about it. I don’t need to hold onto an instance of my command or anything. It’ll call me back when it’s done. It does what I want it to do, and then is released.

ARC converted this code to:

- (IBAction)buttonPushed:(id)sender 
{
    NSURLRequest *req = [NSURLRequest requestWithURL:
            [NSURL URLWithString:@"http://ax.phobos.apple.com.
                  edgesuite.net/WebObjects/MZStoreServices.woa/
                  wa/wsSearch?term=zen"]];

    JSONWebCommand *command = [[JSONWebCommand alloc] 
                  initWithRequest:req];

    command.completionBlock = ^(NSDictionary *result)
    {
        NSLog(@"Complete. Result: %@", result);
    };

    command.finallyBlock = ^
    { 
        NSLog(@"Finished"); 
    };

    NSLog(@"Starting load...");

    [command start];
}

Not much different… but a key issue here… my release is gone!

Of course, that’s exactly what ARC is supposed to do, but WTF! I thought… urm… I’m gonna start it and it’s going to be immediately released! That won’t work!

But it did work. It worked just fine. It appeared all of the cases of this code worked without crash and without issue. How could this be?

Based on my knowledge of what ARC was doing… my command should be deallocated at the end of this method and hence none of the blocks should get called. They were, however, and this was perplexing to me!

I posted a subset of this code on the developer forums, and Greg Parker informed me that if I wanted to get my desired behavior, that is, an object that contains a block which deallocates the object, a good way to do it would be to do:

__block Foo *foo = [[Foo alloc..]];
foo.completionBlock = ^{ foo = nil; };
[foo start];

Essentially specifying an __block modifier for the variable and then setting it to nil in the completion block. Sure enough, this sounded like exactly what I wanted, and is… in other cases than this, probably a perfectly valid pattern to use for this kind of code. Still, I was perplexed that since I had this code sprinkled through my project, why was I not encountering any issues?

Finally, I decided I wanted to track down exactly what the compiler was doing here to educate myself a bit more on how ARC works.

I looked for a tool in Xcode that could give me a listing of where all the retains and releases were being inserted, but I found no joy.

To be clear… since I wasn’t sure what was going on here… I needed to rule out two different issues… First, that the JSONWebCommand wasn’t being over released. If it was, it could ultimately crash my app. Second, that perhaps the JSONWebCommand wasn’t being released. In this case, I might wind up with a leak. The tool to do this in both cases is Instruments.

I knew that the latest version of Leaks is capable now of even detecting leaks that are a result of retain cycles. Retain cycles are among the few cases where ARC might leak memory. This is because one way to get ARC to not release your object is by having it be retained by something that owns it. (i.e.: A owns B which owns A). This is a retain cycle, and ARC does not detect nor prevent it. It’s really easy to make retain cycles using blocks because of the way that blocks capture local variables. For example:

self.foo = [[Foo alloc] ...];
foo.completionBlock = ^{ [self doBar]; };

In this case, foo is owned by self, and the call [self doBar] inside the block also captures self, strongly, within the block. The block is copied by foo, and so any objects captured within it are retained by foo. Since foo is also owned by self, this is a retain cycle. It’s insidious, and not obvious at all when you just look at it. It gets worse too, when you do this:

self.foo = [[Foo alloc] ...];
foo.completionBlock = ^{ [bar doSomething]; };

In this case, bar is a member variable on self. Because it’s a member variable, it still captures self, even though self is not explicitly shown. In other words, this is still a retain cycle.

In the past, we resolved these kinds of retain cycles using techniques that declared a new variable to hold self which is modified with the modifier __block. This is because, in the past, the __block modifier basically made a weak, writable reference on the heap to the variable in question. For example:

__block id blockSelf = self;
foo.completionBlock = ^{ [blockSelf doBar]; }; 

So this would break the retain cycle. Under ARC however, the behavior of __block has been changed! __block variables are now strong, so this will NOT solve your retain cycle! Instead, you should now use the following pattern, which takes advantage of the __weak modifier.

__weak id blockSelf = self;
foo.completionBlock = ^
{
    id strongSelf = blockSelf;
    if(strongSelf)
        [strongSelf doBar];
};

This is the safest way to go, since blockSelf is a zeroing weak reference… when the block executes, if self has been deallocated, then your code won’t crash. Now, if you’re on iOS 4, or Mac OS 10.6, then you don’t have __weak… so instead, you can still get the same behavior that you had before by using __unsafe_unretained in conjunction with __block:

__block __unsafe_unretained id blockSelf = self;
foo.completionBlock = ^{ [blockSelf doBar]; }; 

Just realize that if self gets deallocated your app might blow up. Coder beware!

But anyway… I have digressed… none of this was what was happening in my code. Instruments showed no leaks… and in fact, I could see (by creating a dealloc method on my JSONWebCommand and putting a breakpoint in it) that my command was being deallocated. The only question was if it was being deallocated before I was done with it or not. I then ran the NSZombies instrument on the code… and it showed that it was not being prematurely deallocated. So that left me with the question of… How in the heck is ARC knowing the right thing to do here? So finally, I decided to do some hardcore code spelunking…

I asked around a bit on Twitter, and Stefen Lasser suggested that I use the Xcode debugger to set breakpoints on the ARC runtime methods themselves. You can do this yourself by setting symbolic breakpoints on objc_retain objc_release etc… This can be very noisy, however, so you’ll either want to disable them initially until you hit a specific point in your program, or tweak the conditions on the breakpoint to only break on certain classes. For example, you could set a conditional symbolic breakpoint on objc_retain such that it only fires when it’s parameter is of type JSONWebCommand (this may require some console gdb-fu).

In the end, this is exactly what I did… I basically ran my program up until my block of code… then set my breakpoints on the release/retain methods… and looked up the stack as each was called in turn… and here’s what I found:

This code…

connection = [[NSURLConnection alloc] 
 initWithRequest:request delegate:self startImmediately:NO];

is inside JSONWebCommand… can you spot it? Well it turns out… NSURLConnection retains it’s delegate! I’d gotten so used to delegates that are not retained, I had looked at this code a dozen times and thought “No, that can’t be retaining me… that’s a delegate!” But I traced it up to there, and saw the retain, and I said “What? How can that be retaining self?” I checked the documentation and… sure ’nuff… that’s the way that bugger works. It retains it when set, and releases it when the connection terminates.

So I guess in the end… what did I learn?

Well, I got some practice using the new tools in Instruments. Check them out… they’re excellent! In particular watch the WWDC videos on Instruments. Good stuff.

I also learned a bit about how to trace around inside ARC’s inserted code. Truth be known, I didn’t actually need the release in my block at all even before changing to ARC. So the tool was smarter than me! Less code is always better! I guess the key takeaway here, however, was that ARC wasn’t doing anything surprising. It was doing exactly what it should have done! I would have been far more bothered if it turned out it had some kind of magic it was working. But it wasn’t.

Creating Adapters Using Protocols

Saturday, July 30th, 2011

I have some code I’ll be open sourcing in the next month or so. It uses a third party JSON library to convert Objective-C objects to JSON objects. When I wrote it, the most popular JSON library out there was TouchJSON. Today, although TouchJSON is certainly still popular, there are many other JSON parsing libraries available.

That said, in general, I’d say it’s poor form to require third party libraries when distributing an open source component. It’s difficult enough for people to integrate your code into their projects, let alone bringing in even more code from other libraries. Furthermore, what if the consumer of your component already has chosen a library that does what you need the third party library to do and doesn’t want to add yours?

Decoupling Is Good For You

The root of this problem has to do with coupling. When your code is coupled closely to specific libraries or other classes that you do not provide as part of your distribution, it decreases its reusability.

Because of these issues, I’d prefer not to distribute this code if it’s going to force users to be locked in to using TouchJSON.

Fortunately, Objective-C provides us with some awesome tools to help reduce coupling. The tool I’d like to talk about today is protocols and how you can use protocols to decouple your code from specific frameworks by using it to implement the Adapter pattern.

Even though TouchJSON has various methods for encoding objects to JSON from NSDictionary, NSArray, and other foundation container classes, remember that we don’t want to couple ourselves to TouchJSON. We want to make it possible to use our code with any JSON encoding library. So what we need is to tell users of our code exactly what we need from a JSON library so that they can implement adapters for whatever library they want to use.

This is a perfect case for using protocols.

A protocol allows us to define an interface that other objects can implement. We can then write our code according to the protocol and not the specific interface of the library. This way, users of our code can pass in any object that conforms to the protocol – including our adapter.

Let’s look at some code!

First, to define an protocol, you define it using the @protocol directive.

@protocol MyDoodadProtocol
-(NSString *)encodeDictionary:(NSDictionary *)inDictionary;
@end

As you can see, here we’re defining the MyDoodadProtocol protocol. In it, we’ve defined just one method, -encodeDictionary:. This method is our adapter method for talking to whatever JSON encoding framework we’re using. The implementation of this method is left up to our adapter later.

To use the MyDoodadProtocol protocol, we simply need to pass an object into our MyDoodad which conforms to it. We check this when it’s passed in by declaring that the type of the object is id<MyDoodadProtocol>. This limits the type of argument to an object conforming to the protocol. If we pass something else, it’ll generate a compiler error

@interface MyDoodad : NSObject
{
    id<MyDoodadProtocol> encoder;
}
-(id)initWithJSONEncoder:(id<MyDoodadProtocol>)inEncoder;
-(void)doStuffWithDictionary:(NSDictionary *)inDictionary;
@end

@implementation MyDoodad
-(id)initWithJSONEncoder:(id<MyDoodadProtocol>)inEncoder;
{
    if((self = [super init]))
    {
        encoder = [inEncoder retain];
    }
    return self;
}

-(void)doStuffWithDictionary:(NSDictionary *)inDictionary
{
    // we already know it implements our protocol, 
    // so we can use it here
    // if we didn't know, though, 
    // we could check respondsToSelector or 
    // conformsToProtocol here as well.
    NSString *json = [encoder encodeDictionary:inDictionary];   

    [self doSomethingWithJSON:json]; // ....
}

@end

The actual implementation of the adapter can be as simple as a class which acts as an intermediary. This one uses TouchJSON…

@interface MyDoodadAdapter : NSObject <MyDoodadProtocol>
-(NSString *)encodeDictionary:(NSDictionary *)inDictionary;
@end

@implementation MyDoodadAdapter
-(NSString *)encodeDictionary:(NSDictionary *)inDictionary;
{
    // TouchJSON uses "serializeObject"...
    NSData *data = [[CJSONSerializer serializer] 
                serializeObject:inDictionary error:nil];
    NSString *ret = [[NSString alloc] initWithData:data 
                encoding:NSUTF8StringEncoding];
    return [ret autorelease];
}   
@end

So by doing this, your code is only having to rely on the protocol, and not on the specific implementation of any given library. Users of your code can pass any object they want into the initializer, and your code will use just the interface it’s declared it needs via the protocol. It’s a nice clean way to decouple your code from dependencies.

Why not use inheritance?

Using a protocol is better than using a class and requiring the user inherit from your class because you never know what kind of class hierarchy your user may already be using. She may want to make the adapter from a class that’s already inheriting from something else, or even simply make a category on the encoding library itself. For example:

@interface CJSONSerializer (MyDoodadAdapter) <MyDoodadProtocol>

-(NSString *)encodeDictionary:(NSDictionary *)inDictionary
{
    NSData *data = [self serializeObject:inDictionary 
        error:nil];
    NSString *ret = [[NSString alloc] initWithData:data 
        encoding:NSUTF8StringEncoding];
    return [ret autorelease];        
}

@end

This code actually extends the TouchJSON API directly, and adds the required method directly to the CJSONSerializer class. This can be very convenient and keep us from having to add additional classes to our code. As shown here, categories can be declared to conform to protocols just like classes can.

Is this something I should do all the time?

In a nutshell… no. If you’re using a lot of capabilities from a library, making adapter protocols for everything in the library is impractical and would be a very bad idea. However, if you only need a few methods, providing the ability for users of your code to use an adapter instead of having to be locked into the library you used originally is a great way to provide additional flexibility and make it much easier to integrate your code into their projects. So like all things, use it in moderation and it can be a great tool!

I, For One, Welcome Our New ARC Overlords

Wednesday, June 15th, 2011

So, the LLVM docs have been updated with details about ARC. This means that we can at least talk about the details of the implementation in the compiler and why it’s going to be so cool, even if we can’t talk about the specifics of the implementation in any NDA tools or operating systems.

By all means, you should go read the docs and get the low-down on everything.  But here’s a brief summary of some of the higher level ideas:

First, obviously, you can get rid of your releases, your retains and your autoreleases, instead, you now need to think in terms of strong references vs weak references.

Strong references are essentially your traditional retained variables and weak are the equivalent to your old assign properties.

The default for all variables is to be strong references… that is, they’ll be retained until no one refers to them anymore.  If you define a variable as weak, however, it will not be retained.  This is important for delegates and other cases where retaining a variable might lead to retain cycles. Yes, retain cycles are still potentially an issue.

All variables also are now initialized to nil by default and weak references will also be nilled when deallocated.   The modifiers used to define your variables as strong or weak are __strong and __weak respectively, but again, strong is the default, so if you do nothing, your variables will be strong references.

Speaking of variables… when talking about ARC and variables… ARC only affects Objective-C objects.  It does not impact any C level pointers allocated with malloc or anything like that.

There’s also an additional modifier of __unsafe_unretained which is like weak, but which is not nilled when deallocated.

Variables returned through a parameter that must be autoreleased can also use an __autoreleasing storage modifier.  Mainly you’d use this in cases where you might be doing something like returning an NSError ** or similar through a parameter.

ARC also adds a language construct of @autoreleasepool which works similarly to @synchronized or @try/@catch.  It allows you to define a block of code which has it’s own autorelease pool.

I suspect for those of us who are used to doing manual memory management, we’ll have a lot of discussion about where ARC is inserting it’s releases and retains… I think this is interesting from a “this is how it works” perspective… I’m not sure if that’ll be helpful or harmful in terms of learning it though, since at the end of the day, you’ll want to probably forget about retain and release and change your thinking to strong/weak/autoreleased.

There will be much more to talk about WRT ARC in the coming months, but suffice to say, I’m really excited about it. I was never excited about GC, but am really glad to see ARC come to the language. I think it’ll really help improve Objective-C.

12 Myths About Concurrency in Objective-C

Tuesday, June 14th, 2011

There’s lots of cases where new Objective-C programmers incorrectly apply threads or misunderstand their use. I often see code from well intentioned folks who use threads where they absolutely don’t need them. Consequently, I thought I would put together this list of 12 myths to help guide you along the way to the proper use of threads in your apps.

Myth #1: Threads will make my app faster!

This is probably the most common newbie programmer mistake. Thinking that threads will make your app faster.

They won’t. Your code will execute at exactly the same rate regardless of whether it’s threaded or not. The key advantage that threads provide is that, in the case of a multiple-core machine, they allow you to do two things at once. This can speed processing of certain operations, but only in cases where the different operations are parallelizable. That is, in cases where the operations do not rely on each other for any portion of their calculations.

Even in cases where your operations are parallelizable, if you do not have multiple cores, your code will actually run slower if you add threads, since the processor will be doing more context switches to handle your threads.

http://www.random-ideas.net/Dropbox/Threading.png

So, in fact, the cases where threading will actually improve the performance of your app are confined to a relatively small subset. Still, this subset is important and encompasses many common use cases. Unfortunately, too often threads are applied in areas where they are not needed and where they will not significantly improve performance. The effort required to get threaded code right is substantial, and you need to weigh the benefit to bullshit ratio involved. You should also always profile your app before adding threads. You may find that the use case which you think is causing you problems in fact is not. Measure twice and cut once.

Myth #2: Threads will make my code simpler.

Writing thread safe code is hard. It’s seductive to think that if you could spin specific operations off into background threads, they become easier to manage because you no longer have to deal with things like callbacks, and asynchronicity.

The fact is, that adding threading to a complex app will only make it much, much more complicated. There’s an old saying that goes:

Without threads you have n problems. But with threads you have n+1 problems.

Or, as I like to say:

With threads you have n! problems!

Not only will you still have to deal with all your normal coding problems, you’ll also have to deal with things like locking, synchronization, queuing changes. Your code really becomes a lot more difficult to manage when you add threads.

Myth #3: I need threads to solve my problems with blocking I/O.

This common misconception comes from the fact that there are several synchronous methods on some of the foundation classes such as NSString and NSData which allow you to download content from the Internet. These methods, such as +stringWithContentsOfURL: are tremendously convenient, but block the current thread. Using them is as simple as:

NSString *myStr = [NSString 
                     stringWithContentsOfURL:urlToMyData];

Obviously, you’d never want to block the main thread, so a conscientious coder will often (wrongly) imagine that spinning this operation off into a background thread is a good way to still use these convenient methods. The fact is that this is a bad idea.

Threads can only be terminated when they are checking some kind of control variable and can thus be triggered to exit, such as:

while(keepRunning)
{
    NSString *myStr = [NSString 
                     stringWithContentsOfURL:urlToMyData];
}

Since the +stringWithContentsOfURL method blocks, the keepRunning variable will never get checked. So how do you stop this thread? The fact is, you don’t. There is simply no way to terminate a blocked thread.

This issue alone should be enough to make you walk away, but in case its not, consider that you also have no way to specify a timeout for these methods, you can no longer properly handle complex handshaking such as from authentication, and you lose the ability to interpret status codes that might be returned when accessing the resource.

Because of all this, you should never use these methods.

You might be saying to yourself right now “But I don’t need to worry about those things, I have a very simple use case, and my data will always be available.”

The answer is no. Never use these methods! there’s no need to! The Foundation classes, NSURLConnection and NSURLRequest provide more than enough functionality to do the job properly without blocking and without using threads.

Before I came to Objective-C I wrote a lot of C++, most of it networking code. I know how hard it is to get networking code right. One surprising lesson I learned is that even when writing services that had to handle many incoming connections, threads are almost always still the wrong answer. If you imagine a case where you’re handling hundreds of connections, you really don’t want to spawn and manage hundreds of threads. You’re really much better treating your sockets as a pool and handling I/O on them that way.

Much research has been done on this subject, but one of the best resources I have found is from Dan Kegel in his article, “The C10K problem.” You can go read those docs, and bleed yourself into socket code for the next 5 years of your career, or you can take my word for it: Apple knows what they’re doing here, and they got it right. NSURLConnection and NSURLRequest will handle 90% of the networking needs of most developers.

(How to handle the other 10%? That’s another post!)

A lot of developers will also make the mistake of prematurely optimizing networking code like this when they have large resources they have to download. They imagine that they need to run even NSURLConnection in a background thread. This couldn’t be further from the truth.

NSURLConnection is extremely efficient at downloading even very large files. I’ve never seen a file it couldn’t handle. It will not block your runloop. Your own code, processing those large files, may block the runloop and need to be threaded, but the actual downloading will not.

Myth #4: NSOperation means I don’t have to think about threading issues.

Just because you’re using NSOperation doesn’t mean your code is magically thread safe. NSOperation provides no thread safety facilities whatsoever. It simply provides an easier way to spawn and manage threads by abstracting away the details of the thread itself. All you need to provide is the code that actually does the work. NSOperation does the rest for you.

What this means in terms of our discussion here is that everything I’ve said about writing thread safe code still applies and code you write as part of your NSOperations still needs to be thread safe.

Myth #5: Atomic properties makes my code thread safe

As we’ve already seen, thread safety is a complex subject full of dark alleys and pitfalls. At it’s most fundamental level, even just reading a value from memory can be fraught with peril. When making your classes thread safe, you have to account for both these low level fundamental operations as well as higher logical level relationships, such as setting different variables within your class.

Atomic properties addresses only the issue of accessing your property values. An atomic property insures that the setter of a property cannot modify the property while it is being retrieved. Basically, when you use atomic properties, the accessors generated by the compiler wind up looking something (roughly) like the following:

 //@property(retain) UITextField *userName;
 //Generates roughly

 - (UITextField *) userName {
     UITextField *retval = nil;
     @synchronized(self) {
         retval = [[userName retain] autorelease];
     }
     return retval;
 }

 - (void) setUserName:(UITextField *)userName_ {
     @synchronized(self) {
       [userName_ retain];
       [userName release];
       userName = userName_;
     }
 }

(via objective c – Atomic vs nonatomic properties – Stack Overflow)

When using an atomic property, you will never run into the circumstance where you receive a corrupt value from the getter due to the setter changing the value while you are getting it. This doesn’t mean that the setter won’t change the value after you have received it, and so, thus, it does not fully insure thread safety. It only addresses one part of the full thread safety picture.

Myth #6: Serial operation queues are not threaded.

Just because you’ve made an NSOperationQueue serial by setting it’s maxConcurrentOperationCount to 1 doesn’t mean that the operations you add to that queue will not be run in a background thread. In fact, with the exception of the built-in queue you get from the NSOperationQueue class method, +mainQueue (NSOperationQueue Class Reference) all queues will run in a background thread. In the case of the +mainQueue it actually returns the queue associated with the main thread of your application and runs it on that queue. The main queue is serial.

Myth #7: GCD makes threading easy.

Along these same lines, GCD also does not make working with threads any safer or easier than any other thread mechanism. GCD’s role in Objective-C threading is actually for the purposes of managing thread pools. It’s job is to correctly determine the appropriate number of threads to use for your hardware based on the number of processors and cores your machine has. Although you can use the low level GCD API to add your operations directly to GCD, NSOperation provides a higher level abstraction to the very same mechanism, and is, generally, the preferred way to do it.

Myth #8: Threads Can Be Terminated Safely From Outside The Thread

It’s actually not possible to terminate a thread if the thread itself doesn’t want to be terminated. This is not entirely obvious, but it’s true. This is why most threaded operations utilize a flag to tell them when to exit prematurely. For example:

-(void)myThreadedOperation
{
    while(continueToRun && ![self allStuffIsDone])
    {
        // do some stuff...
    }
}

In this case, we have a background thread that is doing a series of operations. When all the operations are done, it sets the returns true from -allStuffIsDone and exits the loop. However, it also has a flag called continueToRun which its checking on each loop. This flag can be set by an external thread to cause this thread to exit after any iteration. If your background operations will take a long time, you probably want to include a similar design pattern.

Myth #9: I can safely throw exceptions in threads.

What happens when an exception is thrown in Objective-C and not caught? Usually, a crash. 1 What happens when an exception is thrown in a background thread and not caught? The answer is, the one thing worse than a crash: undefined behavior. It might crash… It might crash the whole app… It might crash just the thread… No one knows! It’s undefined. Your thread might even crash, and your app continue running. What do you think your app will do if it expected that thread to later either still be running or have finished?

Although I wouldn’t say that you can’t throw exceptions in threads at all, the important thing to know is that if you do, and it doesn’t get caught, the end result for your app is very bad.

Fortunately, Objective-C doesn’t use a lot of exceptions. So I don’t advocate putting generic exception handlers at the top of all your threaded operations. I point this out more as a “thing to know”. That exceptions can be dangerous in threads, and to be careful when working with code that does throw exceptions.

Myth #10: I can update my gui from background threads.

This one is fairly well known, but worth mentioning anyway. Cocoa and CocoaTouch, the GUI frameworks used on Mac OS and iOS respectively, are not thread safe. You must never update your GUI from a background thread. Whenever you need to trigger a GUI update from a background thread, you should do so on the main thread. Here’s an example of how to do this using the main queue and a block:

[[NSOperationQueue mainQueue] addOperationWithBlock:^
    {
        [self.tableView reloadData];
    }];

Myth #11: Notifications from background threads are executed on the main thread.

Notifications are nothing more than a set of method calls. So when a notification occurs, your notification handler will be called from the thread upon which the notification was triggered. This has some interesting implications.

For example, when you’re saving Core Data objects in a background thread, this notification will be sent from that background thread. Ordinarily, this is a great notification to watch for to update your UI when changes occur. Of course, we already talked about how you can’t update your UI from a background thread, but in addition to this, most of Core Data itself is also not thread safe2. In this case, the objects sent with the notification using the NSInsertedObjects, NSUpdatedObjects, and NSDeletedObjects keys in the userInfo dictionary cannot cross threads, so you can’t use them directly, even if you forward the notification to the main thread.

To handle this problem, you need to use the NSManagedObjectContext method, -mergeChangesFromDidSaveNotification: in the thread of the context which is receiving the notification so it can merge the changes. To do this, you can use the mainQueue again like I showed you before:

[[NSOperationQueue mainQueue] addOperationWithBlock:^
    {
        [self.ctx mergeChangesFromContextDidSaveNotificaton:
                                     inNotification];
    }];

Myth #12: I shouldn’t use threads

Given all these hazards, you might think that you should never use threads. This is not the case. Threads are a useful tool, but like any tool, they have to be respected.

Threads are like the tablesaw of the Objective-C wood shop. They cause more application injuries than all other technologies combined. There’s times, however, when they’re really the best tool for the job! The important things to remember when using threads are:

  • Keep your thread’s data isolated.
  • Simplify the algorithms you intend to use in threads. Make them the “simplest thing that can possibly work.”
  • Learn the API used for insuring thread safety like it’s the back of your hand. Things like NSLock, @synchronized, NSRecursiveLock, etc.

  1. You can install an unhanded exception handler to change this behavior. 

  2. NSManagedObjectContext for example, can’t cross threads either. This is probably worthy of a post all of it’s own someday! 

WWDC First Time Attendee Tipsheet

Sunday, May 22nd, 2011

I actually originally wrote this post 2 yrs ago for WWDC. I figured it was time to update it. Be sure to check out Jeff LaMarche’s post along the same lines here.

Was writing up an email for a friend who is a first time WWDC attendee and thought it might be of interest to others.

SF natives would probably call my list touristy – I don’t know the local lore as much as they do. So be it. I’m not ashamed to be a tourist! ;) I love SF, and have been enough times that I have a few favorite places to go and things to do. Some of these have been covered by other folks as well.

So without further ado…

Some tips for you as a first time WWDC attendee:

  1. Hope your hotel is close to the convention center. SF is the most pedestrian friendly city in the world, and parking is a pain. If it is, plan to NOT rent a car and instead, just take the BART from the airport to the station closest to your hotel. Wear good walking shoes.
  2. Badge pickup begins on sunday. Get it done if you can rather than wait for monday morning.
  3. You’re going to be in an overflow room for the keynote. Just plan on it. Some freaks start lining up the night before the keynote to make sure they get good seats in the main room. Personally, I don’t bother. The view is often better in overflow anyway.
  4. Due to #3 above… plan monday to travel light. You’re going to be waiting in line a LONG time… we’re talking longer than disney land long.
  5. Don’t lose your badge. They do not replace them, and you’re not getting in without one.

More specific to SF rather than WWDC:

  1. The cable cars will take you to most of the interesting things around town. You can get a pass for them at the end-of-the-line stop near the convention center in Hallidie Plaza. The passes allow you to ride as much as you want for a day, 3 days, or a week.
  2. The end-of-the-line stop at Fisherman’s Wharf tends to get a long line. You can sometimes avoid it by walking a few blocks along the cablecar route and hopping on there instead. Those few blocks are uphill, however.
  3. You owe it to yourself to visit Chinatown and Fisherman’s Wharf at the least. Wander the shops, see the sights.
  4. No, you will not be able to get tickets to Alcatraz.
  5. The Ghirardelli Chocolate Factory self-guided walking tour is a great way to spend an evening when nothing else is going on.
  6. The Golden Gate bridge is visible from Fisherman’s Wharf, but if you want a truly postcard view, you might consider taking a bus to the Presidio.
  7. Dress warm. It gets really chilly at night Remember the Mark Twain quote: “The coldest winter I ever knew was a summer in San Francisco.” It’s 100% true. It gets windy and cold, and icky. (Course, maybe it’s my thin Arizona blood talking there.

Food-wise… Chinatown for Chinese (natch) North Beach for Italian. Some would say Fisherman’s Wharf for seafood, but honestly, I have yet to find a good place down there. There’s also some good places on columbus ave. More specifically in no particular order:

  • House of Nanking in Chinatown is without a doubt, the best chinese food I have ever had in my life. It totally looks like a dive, with tables so close together, that you can’t help but become friendly with the strangers beside you, and always a line outside. The way to “do” this place is to allow Mr. Fang, the owner and chef to order for you. He’ll ask you what kind of flavors you like, and you will not be disappointed. Plan about $25 per person. Mr. Fang himself opened a new place very close to Moscone a couple of years ago called “Fang’s” which serves the same cuisine with less of a crowd and less of a dive atmosphere.
  • The Stinking Rose on Columbus Ave. specializes in all things garlic. I’m especially fond of the garlic prime rib. The atmosphere is kitchy, but it’s fun, and you’ll never be able to try so many different garlic based dishes in one place. Suggest you save this for later in the week to avoid lacing your first impressions with halitosis. Vampires need not apply.
  • Puccin & Pinnetti across from the Parc 55 is decent italian. Close and convenient.
  • Mel’s around the corner from Moscone makes an excellent place for breakfast, lunch, or late night coffee fueled meetings. Reasonable prices and good meaty cheeseburgers.
  • New Delhi, also across the street from the Parc 55 is great Indian food, and has a nice quiet bar.

Speaking of food and lunches… your WWDC ticket includes a free box lunch at Moscone each day of the conference. I suggest you take advantage of that. Usually, the food is only barely edible, but that’s not why you’re there. You’re there because that room is filled with your peers, and every table is an opportunity to meet someone new. Seek out tables filled with people you don’t know. Sit down, introduce yourself, and then ask each person what they do and why they’re there. It’s a tremendous opportunity.

I’ll end it here. There’s much much more, of course… parties, sessions, etc etc… But this is enough to get you started. Remember to have a great time, and if you see me, please don’t hesitate to introduce yourself. I love meeting new friends!

Best of luck, and have fun!