iPad gets back to the priorities of the first Macintosh
The first Mac I ever used was a Mac 128, when my Dad brought one home as part of the ground breaking Apple Test Drive promotion. It booted into the Finder quickly even though it used a floppy. It only ran one program at once, so programs (mostly) started and exited quickly and didn't interact. It had a fixed screen size so everyone's experience was the same. There were desk accessories that gave access to limited functionality while applications were running.
Sounds a lot like the iPad (except bigger and black and white - and of course no 3G ;). Seriously, it's Steve Job's core vision all over again. Steve Jobs didn't want the Apple ][ to have any expandability, it was Steve Wozniak who convinced him (correctly) that computers were still very much a hobbyist device and need expandability. The original Mac wasn't supposed to have upgradeable ram - it was the engineers (Burrell Smith I think) who secretly made the circuit board easily upgradeable. Only now, the hardware and connectivity reality has caught up with Jobs' reality: hardware is cheap, expendable and compact - and Apple makes the best. Once again another insanely great device is going to change the place computers have in our lives. 11:08 AM, 28 Jan 2010 by Mark Aufflick Permalink | Comments (1) Debugging release/autorelease issues in Cocoa
So your code crashes with an EXC_BAD_ACCESS in objc_msgSend and there
is *none* of your own code in the stack trace. Bummer. Since all we
know from objc_msgSend is that it's trying to call a method on an
object. Since we got EXC_BAD_ACCESS you can bet your bottom dollar
that it's attempting to call a method on a freed pointer, so there's
no obvious way of finding out what the object was. We can, though,
easily find the method. Read Greg Parker's excellent post So you crashed in objc_msgSend(). For the iPhone
simulator on my Mac I need to do this at the gdb prompt to decode the
eax register:
(gdb) x/s $ecx 0x980530c4: "release"you can see that the selector in the second argument is "release". Now we're getting somewhere, we know an already freed object is trying to be released. Since there is none of our code in the stack trace it's a fair bet that it's happening when the autorelease pool is releasing. There are a few tricks in your toolbox for tracking down over-released objects. There's the NSZombieEnabled, NSAutoreleaseFreedObjectCheckEnabled and other environment variables which will give you better logging rather than just crashing. I've found this is not always reliable (logs from the above builtin debug options showed that the over-release was on an NSCFDate object, when in fact it was an NSNumber). Sometimes you also just want to trace through exactly what is happening with your retain/release/autorelease cycles. That's what we're about to achieve here. Ok, so you have a unit test that replicates this problem right? I use the excellent GHUnit by Gabriel Handford. If not you'll have to play around a bit to narrow down your problem code. In my case, I wanted to confirm that a particular unit test was failing during the autorelease pool release. Best way is to wrap the offending code in a new autorelease pool. Then it will be freed inside your code, which you will see in the stack trace, and confirm you have found the reason. My unit test now looks like: (Note that the code examples, embedded in github gists, are not showing up in my RSS feed. I'll fix that later, but for now please read the original post) Now when I fail with EXC_BAD_ACCESS my stack trace looks like this: Where line 91 of CJTestCJCard.m is the [pool release] call above. So something is being added to the autorelease pool, and is *also* being fully released, or maybe it's being added to the pool more times than it is being retained. There doesn't seem to be a way to interrogate the contents of the autorelease pool (which is a shame) but we log some really useful info by overriding a few methods, like NSObject's release and autorelease methods, so we can see when things are being added to the pool and when things are being released. This is some funky stuff, but since we're only doing it in our unit test class, not code we're going to release you can sleep soundly at night. Here's how I effected logging in release and autorelease. Add this to the top of your unit test class, before your current @implementation: Now in your unit test class @implementation, you can use the setupClass method to effect the method implementation switcharoo: Now your log will be filled with log lines like: This can help when tracking down tricky releasing bugs. Note that not all classes seem to comply. For instance I see plenty of log lines for NSCFString, but never any release lines. I assume that NSCFString release implementation is a bit different since it's a toll free bridged object - getting that to log is an exercise left for the reader! If you're interested in the functions I used above to interact with the runtime, check out the Introduction to The Objective-C Programming Language and Objective-C Runtime Reference. Note that the code above works fine in the iPhone simulator. It should be fine on 64 bit Mac apps, but you may need to diddle the method structs manually in 32 bit Mac apps since they use the legacy Objective-C runtime (which you can read about in the Objective-C 1 Runtime Reference). Also note it won't work on the iPhone itself, so to save constantly commenting out code, you can wrap the offending code in #if TARGET_IPHONE_SIMULATOR #endif pairs.
12:38 PM, 14 Jan 2010 by Mark Aufflick Permalink | Comments (0) Wow - twitter has sure killed my blogging
I'm not the first to note this, but my blogging sure has taken a huge hit thanks to Twitter (where you can follow me as @markaufflick). It's been a bit over a month since my last post. Contrast that with the fact that in the more than 6 years I've been writing this blog I've only not blogged in April 2008, March 2009 and December 2009.
And that's a shame - because some things I blurt out on twitter, either technical or personal, could stand more thought and word-smithing than 140 characters allow. So one of my 2010 resolutions is to blog more - even if I tweet first. I'm even open to topic suggestions. 03:37 AM, 03 Jan 2010 by Mark Aufflick Permalink | Comments (0) |
Archive
January 2010 October 2009 September 2009 August 2009 July 2009 June 2009 May 2009 April 2009 February 2009 January 2009 December 2008 November 2008 October 2008 September 2008 August 2008 July 2008 June 2008 May 2008 March 2008 February 2008 January 2008 December 2007 November 2007 October 2007 September 2007 August 2007 July 2007 June 2007 May 2007 April 2007 March 2007 February 2007 January 2007 December 2006 November 2006 October 2006 September 2006 August 2006 July 2006 June 2006 May 2006 April 2006 March 2006 February 2006 January 2006 December 2005 November 2005 October 2005 September 2005 August 2005 July 2005 June 2005 May 2005 April 2005 March 2005 February 2005 January 2005 December 2004 November 2004 October 2004 September 2004 August 2004 July 2004 June 2004 May 2004 April 2004 March 2004 February 2004 January 2004 December 2003 November 2003 October 2003 September 2003 August 2003 Blog Categoriessoftware (24)..cocoa (12) ..heads up 'tunes (5) ..ruby (4) ..lisp (1) ..perl (2) ..openacs (1) mac (18) embedded (2) ..microprocessor (2) ..avr (1) electronics (3) design (1) Notifications Request notifications
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||








Request notifications