Strange Seg Fault In Simple Cocoa App

I just got Aaron Hillegass’ 3rd edition of Cocoa(R) Programming for Mac(R) OS X (3rd Edition) and am working through it as if I never went through the 2nd edition. (It’s been so long since I did any Cocoa, that seemed like the smart thing to do.) Anyway, I’m in Chapter 4 on memory management and things were going fine. Until all of a sudden, the program started dying with a segmentation fault. After trying to figure out what I’d done wrong, I figured I’d mistyped something and just wasn’t seeing it, so I reverted my changes back to what I had in my Subversion repo. I then started making the changes again. And again the program died with a segfault. 

Any time I’m working through a programming book, I always type all the examples in by hand, rather than downloading pre-written code. I learn better that way. But in cases like this, I don’t have a problem with looking at the author-provided code to see where I went wrong. I downloaded the solutions from Aaron’s site and started comparing. I found the problem pretty quickly.

Originally, the code for creating the NSCalendarDate object for today’s date was

NSCalendarDate *now = [[NSCalendarDate alloc] init];

which, when you later add the code to release it, would have worked fine. But at some point between when I wrote that line of code and when I added the release, Aaron mentioned a convenience method on NSCalendarDate for getting back an autoreleased date object. That code looks like this

NSCalendarDate *now = [NSCalendarDate calendarDate];

I had changed my code to use that instead of the original version. That was in Chapter 3. So, when I hit Chapter 4 and added the call to release the date object, I ended up with my segfault. The chapter assumed that you still had the alloc & init calls, and so made no mention of the calamity that would ensue if you had switched to the other way of getting today’s date.

What made this difficult to find was when the segfault occurred. It didn’t happen when I called release on the date object. It happened on this line

[pool drain];

which is one line before the program ends. That’s boilerplate code there, so it was really strange that it was barfing. The reason this caused the problem is that this way of getting a date is autoreleased, which means that unless I retain it somewhere, it’s going to get deallocated when the NSAutoReleasePool is deallocated. But when I called release on it, I ended up setting it’s retain count to 0, so when the pool was drained, it ended up sending a release message to an object that had already been deallocated, which is a no-no.

Bottom line is that had this been a big program, this could have been really hard to track down. Of course, turning on the Objective-C 2.0 garbage collector would have solved the problem too, but then you have a Leopard-only program.

A Few Things I Hate About iPhone OS 2.0

I love the new iPhone 2.0 OS, mostly, though I really think they should have let it bake for another couple of months before releasing it. There are parts of it that just don’t feel fully cooked. For instance, one application dying should not cause the entire phone to reboot. That doesn’t happen in OSX, nor does it happen in Linux. It does happen in Windows, but that’s another story. It’s happened to me at least six times with different apps, and that’s just not cool.

Next, it’s really difficult to actually delete an application from the phone. I’ve figured it out, but here’s what I went through. The first time, I deleted it from the Applications panel of iTunes and said “yes” when it said that they would be removed from the phone the next time I did a sync. Perfect. Except it wasn’t. The next time I did a sync, I got a dialog saying that there was purchased content detected on the phone and did I want to transfer it. A parenthetical note advised that failure to do so would result in the content being removed from the phone. I answered “transfer” because I wasn’t sure if I’d installed anything directly to the phone or not. Of course, the only content that was on the phone that wasn’t in iTunes was the apps I’d just deleted. Actually, the very first time I tried to delete apps this way, I didn’t get the “purchased content on phone” message, because I’d seen it once before and had checked “always transfer” as the default. That means that it would be impossible to ever remove apps this way, since iTunes would always transfer them from the phone back into iTunes.

So then I tried deleting the apps from the phone itself. I pressed the icon and held it down until the screen went “wiggly” and then pressed the ‘X’ on the icons I wanted to delete. They got removed just fine. Until I did a sync with iTunes again, at which time they were dutifully reinstalled.

What this means is that there is only one surefire way to delete apps: delete them from both the iPhone and iTunes before doing a sync. You could just delete them from iTunes and then answer “don’t transfer” from that dialog the next time you sync, but you have to make certain that the only “new” content on the phone is the deleted apps, and not something that you want to hold on to. Good luck with that.

Finally, I hate the fact that every time I do a sync, iTunes will gladly spend 20 minutes backing up the iPhone. It apparently goes brute force and just backs up everything on the phone, whether it needs to or not. Some of the installed apps, like Apple’s Texas Hold’Em, have tons of images and audio files, which take forever to backup. And once those files have been backed up, there’s no reason to ever back them up again; they won’t ever change! A little checksumming of files could go a long way towards solving this.

I still love my iPhone and the ability to install apps on it is awesome. I’ve paid my $99 to Apple to get into the developer program, and as soon as I come up with something decent that needs writing, I’m going to write it. So even though this post contained the word “hate,” I still love you, iPhone. XX OO XX

A day or so ago Apple began seeding iPhone OS 2.0.1 to developers, so I’m hoping that goes GA quickly and that it addresses some of these problems. Just like Leopard had problems at launch and a relatively quick point release solved them, that’s what I’m hoping for with the iPhone.

07-26-2008 16:20 Update: When I sat down to write this post, it was originally “Three Things I hate…” but at the end, I’d really only included two. So I changed the name. But a little while ago, I remembered the third thing, and that’s when you update apps with new versions, they don’t stay where I had them. For example, just this morning, UrbanSpoon had an update and when it was updated, it moved from page 2 to page 5. That’s very uncool, too.