On indie iOS and Mac development.

Archive for October, 2011

The Correct Way to Avoid Capturing Self in Blocks With ARC

Saturday, October 15th, 2011

I briefly talked about the new pattern for avoiding memory leaks in blocks that capture self in my previous post about debugging ARC. However, I thought it would be worthwhile to discuss it in more detail to explain the rationale behind it.

To recap, the old pattern to avoid capturing self in blocks looked like this:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __block Foo *blockSelf = self;
    bar.block = ^
    {
        [blockSelf.baz doSomething];
    };
}
@end

The key to this code is that we want to avoid referencing self directly in the block since all variables accessed in the block will be retained by the block. If self owns the block, even indirectly, then this will lead to a retain cycle. Therefore, we use the __block keyword to create a temporary reference to self, which we then use instead of self inside the block. Unfortunately, ARC obsoletes this method by making __block references strong. So we need a new pattern to solve this problem.

The naive approach is to simply grab a weak reference to self as shown in the following code listing:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        [blockSelf.baz doSomething];
    };
}

@end    

Really, this is pretty close to what we intended in the old pattern anyway right? We grab a weak reference to self, then use it in our block. No retain cycles. There’s a few problems here, however.

The problems center around the question of what happens when self gets deallocated before or during block execution. It may seem at first blush that this wouldn’t be a big deal since blockSelf is a weak reference and will be zeroed out when deallocated. Since messages to nil are harmless this should be ok right?

Well, it might be ok if ALL the messages in your block wind up doing nothing, but what if self is deallocated on another thread half way through the execution of this block? What if only half of your calls succeed? Could it leave your object in a bad state? Possibly! But there’s a worse problem lurking here… Consider the following, slightly different snippet…

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        [baz doSomething];
    };
}

@end    

In this case, we’re referencing the member variable (bad) directly, not through the accessor. This still captures self so that it can access the member variable, but when it does so, the runtime does not go through the accessor. Instead it uses a direct C level pointer dereference. In other words, that code compiles to something like this:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        [self->baz doSomething];
    };
}

@end    

So, if self gets deallocated in the midst of your block, then it’s possible you could get a crash since you’re directly accessing the member variable via a pointer dereference. This pattern does not obey the rule of messaging nil since you’re not messaging anything.

Because of these problems, the safest thing to do is to get a weak reference to self outside your block, then, at the top of the block, get another strong reference to self so that it doesn’t get deallocated during your block. You can then check to see if you got the strong reference, and if not, just drop out… But if you did, then you should be safe. So, basically, the preferred pattern is now:

@implementation Foo
@property (strong) Bar *bar;
@property (strong) Baz *baz;

-(void)aMethod
{
    __weak Foo *blockSelf = self;
    bar.block = ^
    {
        Foo *strongSelf = blockSelf
        [strongSelf.baz doSomething];
    };
}

@end

To be clear, this code does not guarantee thread safety, you may still need to add @synchronize blocks or thread locks, but certainly this is safer than the old pattern and it addresses all the issues shown previously. Code accordingly!

Twitter: The Broadcast Medium

Thursday, October 13th, 2011

Daring Fireball links to an article this morning about the iOS 5 Twitter integration, and I had a thought:

It seems to me that a big use case of communication that we use today is about sharing “bits”. I don’t mean bits in the computer science way of thinking about bits, I mean bits as in small bits of information. Links, photos, moments, quick jokes, etc. Snippets from the web. And it seems to me that there’s really three “modes” of that communication:

  • Personal and Immediate – Where I want to share this with one particular person right now.
  • Personal and Delayed – It’s not important enough to interrupt my recipient now, but I want to drop off a note to someone for them to read at their leisure.
  • Public – I want to share this with everyone.

It seems like each of these currently has an ideal outlet in iOS 5.

  • Personal and Immediate – iMessage
  • Personal and Delayed – Email
  • Public – Twitter

Are there other “modes” of communication for these snippets that are missing? Feels like this covers everything. And that’s interesting.

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.

ARC, Exceptions and Objective-C

Thursday, October 6th, 2011

Reading through the ARC documentation, I came across this passage:

7.6. Exceptions By default in Objective C, ARC is not exception-safe for normal releases…

 

Rationale: the standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option.

Emphasis, mine… pointing this out because I think a lot of programmers who come from Java, C++, Python, etc seem to have the belief that exceptions are a tool that should be used in ordinary error conditions.  This could not be further from the truth.  Many of these other languages use exceptions excessively… to the point that they almost become like flow control mechanisms.

In Objeective-C exceptions are meant to be used ONLY in truly exceptional conditions.  Cases where you’re willing to have your app crash if they occur.

Code accordingly.