If you’ve ever done any iPhone development, you’ve probably had an accident with the (nonatomic, retain) methods. These methods are difficult to use in the case where you’re working with multiple threads. Our application does not do this, but we do utilize the OpenGL ES 1.1 framework. Have a look at the following console log from the other night when my brother was beta testing our application with some friends at a bar.
Process: myExampleApp [800] Path: /var/mobile/Applications/5D234CF0-1234-4E2F-9A7F-14175F39A0B6/myExampleApp.app/myExampleApp Identifier: myExampleApp Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] Date/Time: 2009-07-19 23:20:40.285 -0700 OS Version: iPhone OS 3.0 (7A341) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Codes: KERN_PROTECTION_FAILURE at 0x00000008 Crashed Thread: 0 Thread 0 Crashed: 0 libobjc.A.dylib 0x30011940 objc_msgSend + 20 1 libobjc.A.dylib 0x3001313c objc_setProperty + 160 2 myExampleApp 0x000126e6 -[GameUIView setBasicObj:] (GameUIView.m:36) 3 myExampleApp 0x0000f694 -[GameUIView setupView] (GameUIView.m:404) 4 myExampleApp 0x0000ec42 -[GameUIView start] (GameUIView.m:173) 5 myExampleApp 0x00002816 -[CoreViewController playGame] (CoreViewController.m:79) 6 myExampleApp 0x00005e80 -[SplashGLUIView touchesEnded:withEvent:] (SplashGLUIView.m:606) 7 UIKit 0x309a60d4 -[UIWindow _sendTouchesForEvent:] + 520 8 UIKit 0x309a5464 -[UIWindow sendEvent:] + 108 9 UIKit 0x30936e3c -[UIApplication sendEvent:] + 400 10 UIKit 0x30936874 _UIApplicationHandleEvent + 4336 11 GraphicsServices 0x32046964 PurpleEventCallback + 1028 12 CoreFoundation 0x30254a70 CFRunLoopRunSpecific + 2296 13 CoreFoundation 0x30254164 CFRunLoopRunInMode + 44 14 GraphicsServices 0x3204529c GSEventRunModal + 188 15 UIKit 0x308f0374 -[UIApplication _run] + 552 16 UIKit 0x308eea8c UIApplicationMain + 960 17 myExampleApp 0x000020b6 main (main.m:14) 18 myExampleApp 0x0000202c start + 44 |
The core method here that is the issue is implemented as:
//in the .h file. @property (nonatomic, retain) NSObject *basicObj; //in the .m file. @synthesize basicObj; - (void)setupView { if (self.basicObj != nil) { [self.basicObj release]; self.basicObj = nil; //line 404, this is where the error is located. } } |
As you can see, the issue appears to be based on how we access the basicObj object. The definition of a SIGBUS error, is pretty straight forward. We are generically having some sort of memory issue.
As of this writing, I’m still doing extensive testing and I’ll update this post if I find a better solution. Here is what I’ve found to work. I’m beginning to wonder if there is a funny timing issue with the “release” methodology. I’ll make sure to post back here if I find there to still be an issue or I find a better solution. Comments are appreciated.
- (void)setupView { if (self.basicObj != nil) { [basicObj release]; basicObj = nil; } |
I'm a software developer focused on all facets of enterprise solutions and technologies. Currently, I'm enjoying developing iPhone applications at night while spending much of my day working on Java, .Net and database implementations.

#1 by Matthias on August 28th, 2009
Hi,
I had the SIGBUS problem with the CLocationManager. Unfortunately not on a 3GS or an Ipod 2 G with OS3.0 / 3.01.
Can it be device dependent ? It’s hard to track an error if you don’t get it …
Matthias
#2 by Chris Danielson on August 28th, 2009
Matthias,
I should have mentioned that we were using the iPhone 3G phones for our testing. It was very awkward because I was never able to reproduce it. All I know is that after I patched the source code and my brother re-applied it to his phone, the issue just sort of disappeared. It’s never re-emerged since.
Thanks for the comment!
Regards,
Chris
#3 by Aaron on November 3rd, 2009
Hey Chris, thanks for the post –
I just had the SIGBUS error reported today from a beta tester. I’ll give your solution a try – I haven’t been able to reproduce the issue and it doesn’t seem like the code I have in places should cause this problem – here is what I was doing:
id goToView = [searchNearMeViewController view];
I changed that to:
id goToView = [self.searchNearMeViewController view];
The searchNearMeViewController is a freshly allocated & initialized object so it shouldn’t be able to be null. I’ll cross my fingers…
#4 by sujal on December 7th, 2009
Aren’t you just over-releasing the object in the first example?
you release the instance variable, then set the property to nil, which also releases the instance variable.
Am I reading that incorrectly?
Sujal
#5 by Chris Danielson on December 7th, 2009
Sujal,
Thanks for the comment. You might be onto something. Perhaps operating on the “self.” somehow implied directly manipulating the local variable rather than using the getter/setting generated by the annotations.
Without assuming much about how much objective-c you’ve done, it’s always a good plan to set your variables/properties to a known “nil” value after you release them. Otherwise, if and when you attempt to operate on the variable later, you won’t know if it’s been allocated, etc. It will appear as junk and because of that, you might just get a nasty explosion in your code base.
This link explains the nil basics:
http://stackoverflow.com/questions/1210776/objective-c-difference-between-setting-nil-and-releasing
So there really isn’t a double release issue. It was something else in the Apple iPhone that blew up my app at that time. It’s very baffling and with the closed off garden that Apple binds us with, I don’t imagine I’ll ever solve this one, other than knowing that somehow after a clean recompilation and slight modification, the code base began functioning predictably.
Regards,
Chris
#6 by Wain on January 6th, 2010
Sujal is correct, you are over-releasing.
You’re right that you should set released variables to nil. The stack overflow page you reference points out how you’re over-releasing before doing this however.
Your code:
[self.basicObj release];
self.basicObj = nil;
Translates into (not literal):
[[self basicObj] release];
if(basicObj != nil) // which it doesn’t
{
[basicObj release];
basicObj = nil;
}
Where as your final code doesn’t translate into anything as it isn’t using your simulated accessor methods (because it doesn’t access the basicObj property).
#7 by Chris Danielson on January 6th, 2010
Wain,
Great point! Thanks you for the correction.
#8 by Nicolás on July 29th, 2010
Hi Chris,
Thanks for the article, it’s been really useful.
I’m having problem with an iPhone application. We have developed it using Xcode 3.2.3 and SDK 3.2. It runs perfect on iPhone with iOS 3.1.3 and in the simulator (3.2 and 4.0).
But, when we deliver the ipa file to the client, the application crashes sometimes.
He sent the crash logs to us but the only thing we can deduct from it is that the problem is related with memory management.
Is there a way to get more accurate crash logs from our client?
Ty.
#9 by Chris Danielson on July 29th, 2010
Nicolas,
Though I wouldn’t recommend this for anything but an “ad-hoc” debug test, you might consider writing your own logging tool that includes a quick email feature to help you troubleshoot this issue. So you would write a #define macro that could be toggled off for your final Apple store releases in the future that perhaps writes logs into a SQLite database (because this runs fast on the iPhone) and then a test UIButton that the user can click at any time… this would then scoop up all that data and allow the customer to email it.
Just an idea…