views:

166

answers:

1

I've posted a couple of questions before, trying to work out why I'm getting a EXC_BAD_ACCESS, and I've done a bit of debugging

See here: http://stackoverflow.com/questions/2024266/help-debugging-iphone-app-excbadaccess/2024391#2024391

and:

http://stackoverflow.com/questions/2024654/overreleasing-here

So, I think I've discovered what's going on.

From my log, I'm getting this:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000f
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x00003ebc objc_msgSend + 20
1   MyApp                       0x0000378a -[PictureView clearPage] (PictureView.m:79)

At first I thought the problem was a released object being sent a message within the 'clearPage' function, however since talking to a friend, I am led to believe that the PictureView object itself might already be released.

This is confirmed by my logging output:

Fri Jan  8 20:28:32 unknown MyApp[2224] <Warning>: Picture View Unloaded
Fri Jan  8 20:28:32 unknown  MyApp[2224] <Warning>: Memory warning from Picture view
Fri Jan  8 20:28:34 unknown  MyApp[2224] <Warning>: Scaling image
Fri Jan  8 20:28:36 unknown  MyApp[2224] <Warning>: Attempting to save image to disk
Fri Jan  8 20:28:37 unknown  MyApp[2224] <Warning>: Saved file to: /var/mobile/Applications/065C0D37-95C1-41D4-98F0-16A3555682CD/Documents/MyImage1.jpg
Fri Jan  8 20:28:37 unknown  MyApp[2224] <Warning>: Clearing page
Fri Jan  8 20:28:40 unknown ReportCrash[2225] <Notice>: Formulating crash report for process  MyApp[2224]
Fri Jan  8 20:28:41 unknown com.apple.launchd[1] <Warning>: (UIKitApplication:com.yourcompany.MyApp[0xb8e1]) Job appears to have crashed: Bus error

So, my guess is the view that I'm using is being unloaded after getting a memory warning caused by the imagepicker...

And my question is, how can I stop this from happening? I obviously need to call the clearPage method of the PictureView, but I can't if it's unloaded.

+3  A: 

Is PictureView retained in your controller (I'm assuming it's a subview of your controller's view)? If it's not retained, then you've got a dangling reference. When your view controller is not frontmost, and it receives a -didReceiveMemoryWarning message, by default it will release its view member. If you have pointers into subviews of that, and they're not retained, you'll end up in this situation.

The first thing to try is overriding -didReceiveMemoryWarning and calling clearPage:

- (void) didReceiveMemoryWarning {
    [myPictureView clearPage];
    myPictureView = nil;
    [super didReceiveMemoryWarning];
}
Ben Gottlieb
Sorry, clearPage isn't doing what the name hints at. It just prepares the view for redrawing by clearing it's subviews. PictureView is a view pushed from the rootviewcontroller: PictureView *picView = [[PictureView alloc] initWithNibName:@"PictureView" bundle:nil]; [self.navigationController pushViewController:picView animated:YES]; [picView release]; Should I be releasing this here?
mac_55
So PictureView is a ViewController? It sounds like you've got a dangling pointer problem. Check for assigned outlets (as opposed to retain). Also, override didReceiveMemoryWarning and break there; call the inherited and then make sure all your outlets are 'sane' values.
Ben Gottlieb
I've made the PictureView an outlet and set it to (nonatomic, retain) in the rootviewcontroller. Unfortunately this crashing doesn't happen every time, so it's really hard to test. It's getting on my nerves now :(
mac_55
If you're testing on the sim, try simulating a memory warning using the menu option "Simulate Memory Warning"
Ben Gottlieb
Thanks! What do you mean by 'call the inherited'? Not sure what I'm looking for here
mac_55
Aha! Managed to reproduce this problem and get this: [UIScrollView subviews]: message sent to deallocated instance 0x4a34620. The scrollview is a subview of the PictureView. I've checked that I'm using (nonatomic, retain) on this scrollview within PictureView - any ideas? Sorry to be a pain!
mac_55
would have to see your code, but you are getting closer! Call the inherited means: call the super class's implementation of the method: [super didReceiveMemoryWarning]
Ben Gottlieb
Yep, looks like what's happening is the warning is being called on the rootviewcontroller, then on the pictureview controller which in turn is releasing the scrollview (which is a subview of the picture view). Now all I need to do is work out how to stop the scrollview from being released. :D
mac_55
GOT IT!!! Looks like I was being too efficient on the old releasing. Had this pesky line of code in my viewDidUnload method: [scrollView release]; Thank you so much for your help!! I've learnt a lot of debugging tips on my way too. Valuable lesson.
mac_55