I am newbie here. i am trying to build a quiz app and while my app runs fine for the first iteration of the quiz it exits without any console errors on the second run. PAsting all the code below for reference.
It seems like when i re-run the quiz, -(void) loadNextWord function below does execute but nothing happens after that.
Please help!
Thank you!
Dump from the debugger:
My line 14 in main func is int retVal = UIApplicationMain(argc, argv, nil, nil);
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Program received signal: “EXC_BAD_ACCESS”.
(gdb)
#0 0x025f0907 in objc_msgSend ()
#1 0x05f28da0 in ?? ()
#2 0x023cfc9d in _CFAutoreleasePoolPop ()
#3 0x0001ee67 in -[NSAutoreleasePool release] ()
#4 0x002cfe7f in _UIApplicationHandleEvent ()
#5 0x02d73822 in PurpleEventCallback ()
#6 0x02474ff4 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#7 0x023d5807 in __CFRunLoopDoSource1 ()
#8 0x023d2a93 in __CFRunLoopRun ()
#9 0x023d2350 in CFRunLoopRunSpecific ()
#10 0x023d2271 in CFRunLoopRunInMode ()
#11 0x02d7200c in GSEventRunModal ()
#12 0x02d720d1 in GSEventRun ()
#13 0x002d3af2 in UIApplicationMain ()
#14 0x00002880 in main (argc=1, argv=0xbfffef94) at /Users/vbhardwaj/Documents/ObjectiveC/FinalProject/FunWords/main.m:14
Looking at the stack trace you see the line
[NSAutoreleasePool release]
This tells me that you have released an object too many times i.e. something like :
NSString *string = [NSString stringWithString:#"Hello"]; // This string is autoreleased
[string release]; // This line won't crash but is WRONG!
The above code will not crash immediately but the string will be released and dealloc'd. However, because it's also autoreleased the autorelease pool will try to release it again at some point in the future. You don't know when and will get a random crash.
You've probably done something like that :)
The problem is with multiple-releases.
To be able to properly debug your code, even include files are nessasary.
I can see that you are releasing wordImageView in your code.
You shouldn't do that.
What you should do is to take advantage of properties and do something like
self.wordImageView = nextImageView;
[nextImageView release];
instead of
[wordImageView release]; // release the flagView's memory
wordImageView = nextImageView; // reassign flagView to the new view
You can always use autorelease pools too, but this comes with memory penalty issues.
Btw, although the problem seems to be in the main loop, it isn't there. That is only the location of where the autorelease pool is cleaned, and the problem appears.
In any case, probably have a look at your code and make sure all 'alloc' is handled by a 'release' of the same object inside the same selector.
Related
I am on Xcode 4.5.1. I think this is relatively new behavior I am seeing.
I prefer to develop and test my projects with the "All Exceptions" breakpoint enabled.
I have been running into a scenario where I am loading thumbnail images to cells in a tableview, where I am getting a __cxa_throw exception. When I click the "Continue program execution" button, Xcode continues its merry way. I get the thumbnails. App seems to work fine. I am looking for some tips on how I can determine if this is something safe to ignore. Like maybe some pointers on understanding the stack trace? Or something else?
Here is the snippet of code:
NSString *imageStr = item.thumbURL;
imageStr = [imageStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *imageURL;
if (![imageStr isEqualToString:#""]) {
imageURL = [NSURL URLWithString:imageStr];
NSLog(#"imageURL: %#",imageURL);
if (imageURL == nil) {
NSLog(#"imageUrl was nil for string: %#",imageStr);
} else {
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
//spinner.frame = CGRectMake(cell.imageView.frame.size.width/2,cell.imageView.frame.origin.y + cell.imageView.frame.size.height/2,cell.imageView.frame.size.width,cell.imageView.frame.size.height);
spinner.frame = CGRectMake(10,20,40,40);
[spinner startAnimating];
[cell addSubview:spinner];
dispatch_queue_t downloadQueue = dispatch_queue_create("thumbnail downloader", NULL);
dispatch_async(downloadQueue, ^{
NSLog(#"Network request for tour_thumb image: %#",imageStr);
UIImage *img = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner removeFromSuperview];
UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(8, 8, cell.contentView.frame.size.width/2 - 16, cell.contentView.frame.size.height - 16)];
imgView.image = img;
[cell.contentView addSubview:imgView];
});
});
dispatch_release(downloadQueue);
}
}
Here is what I see on the stack trace:
#0 0x34a9c524 in __cxa_throw ()
#1 0x387014ce in AddChildNode(XMP_Node*, XML_Node const&, char const*, bool) ()
#2 0x38700d22 in RDF_LiteralPropertyElement(XMP_Node*, XML_Node const&, bool) ()
#3 0x3870094e in RDF_PropertyElementList(XMP_Node*, XML_Node const&, bool) ()
#4 0x38700608 in ProcessRDF(XMP_Node*, XML_Node const&, unsigned int) ()
#5 0x3871480a in XMPMeta::ParseFromBuffer(char const*, unsigned int, unsigned int) ()
#6 0x387095c0 in WXMPMeta_ParseFromBuffer_1 ()
#7 0x38725578 in TXMPMeta<std::string>::ParseFromBuffer(char const*, unsigned int, unsigned int) ()
#8 0x387254de in TXMPMeta<std::string>::TXMPMeta(char const*, unsigned int) ()
#9 0x38722b70 in CreateMetadataFromXMPDataInternal(char const*, unsigned long, unsigned int) ()
#10 0x38739a50 in readXMPProperties ()
#11 0x386a01fc in readXMPData ()
#12 0x3868cec8 in initImageJPEG ()
#13 0x3868c2ee in _CGImagePluginInitJPEG ()
#14 0x3867e274 in makeImagePlus ()
#15 0x3867ddde in CGImageSourceCreateImageAtIndex ()
#16 0x38e117b6 in _UIImageRefFromData ()
#17 0x38e116c6 in -[UIImage initWithData:] ()
#18 0x0004cb0a in __57-[ViewController tableView:cellForRowAtIndexPath:]_block_invoke_0 at ViewController.m:335
#19 0x313fc792 in _dispatch_call_block_and_release ()
#20 0x313ffb3a in _dispatch_queue_drain ()
#21 0x313fd67c in _dispatch_queue_invoke ()
#22 0x31400612 in _dispatch_root_queue_drain ()
#23 0x314007d8 in _dispatch_worker_thread2 ()
#24 0x394767f0 in _pthread_wqthread ()
#25 0x39476684 in start_wqthread ()
This is obviously deep within the implementation and C++ exceptions can be part of the normal flow, if they've decided to use exceptions to signal errors internally.
If you aren't writing any C++ yourself then it is safe to ignore.
Just trap the standard Objective-C exception:
objc_exception_throw
Go here:
And do this:
To turn this:
into this:
You'll still get a lot of the benefit of adding a breakpoint, but won't have your app crash for stuff you probably aren't responsible for anyway. Now if you are working with C++ then you darn better worry about it.
I seem to be getting a crash right after doing [[CCDirector sharedDirector] popScene]. I am not really sure why. Any clues would help, thanks!
Crashlog:
#0 0x99e5ef84 in objc_msgSend ()
#1 0x302d543a in __NSFastEnumerationMutationHandler ()
#2 0x00046b46 in -[CCScheduler tick:] (self=0x1919ac0, _cmd=0x7b682, dt=0.0333320014) at /Users/Sup3rpanda/Dev/My Projects/Puzzle/libs/cocos2d/CCScheduler.m:211
#3 0x0001fb52 in -[CCDirector mainLoop] (self=0xf10a30, _cmd=0x76272) at /Users/Sup3rpanda/Dev/My Projects/Puzzle/libs/cocos2d/CCDirector.m:208
#4 0x305355cd in __NSFireTimer ()
#5 0x302454a0 in CFRunLoopRunSpecific ()
#6 0x30244628 in CFRunLoopRunInMode ()
#7 0x32044c31 in GSEventRunModal ()
#8 0x32044cf6 in GSEventRun ()
#9 0x309021ee in UIApplicationMain ()
#10 0x00002e94 in main (argc=1, argv=0xbfffef60) at /Users/Sup3rpanda/Dev/My Projects/Puzzle/main.m:13
Scheduled timer:
tGridTimer = [[CCTimer alloc] initWithTarget: self selector: #selector(gridSlideUpForced2:) interval: sGridSpeed];
[[CCScheduler sharedScheduler] scheduleTimer:tGridTimer];
Bit of CoCos 2d code that appears to be related to crashing:
-(void) tick: (ccTime) dt
{
if( timeScale_ != 1.0f )
dt *= timeScale_;
for( id k in methodsToRemove )
[scheduledMethods removeObject:k];
[methodsToRemove removeAllObjects];
for( id k in methodsToAdd )
[scheduledMethods addObject:k];
[methodsToAdd removeAllObjects];
for( CCTimer *t in scheduledMethods )
impMethod(t, fireSelector, dt);
[[CCScheduler sharedScheduler] scheduleTimer:tGridTimer];
Are you cleaning up your timers in onExit or dealloc in your scene class? Could be the scene still thinks some of the schedulers are still running
I have an application which used top bar navigation and a MapView. On the map view I have placed some annotations and when selecting an annotation, pressing the disclosure button to go into a subview and then going back to the MapView using the back button my application crashes. It does not give me any errors.
Can anyone help me figure out why my application keeps crashing?
I have made a short video showing this mysterious crash (because I'm afraid that I do not explain it very well)
The video can be seen on this link http://snuzzer.dk/pub/iPhoneAppMapKitCrash.mov
Please tell me if you need to see any code in order to determine the reason for the crash. I am not sure what code would be necessary for this as I do not get any error.
EDIT: This is the output of my stack trace:
#0 0x01275a63 in objc_msgSend
#1 0x0586c860 in ??
#2 0x0037ef1d in -[UINavigationController setDisappearingViewController:]
#3 0x0037c4f6 in -[UINavigationController _clearLastOperation]
#4 0x0037ce3f in -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
#5 0x00509e23 in -[UINavigationTransitionView _notifyDelegateTransitionDidStopWithContext:]
#6 0x0050afd2 in -[UINavigationTransitionView _cleanupTransition]
#7 0x002f6665 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
#8 0x002f64f7 in -[UIViewAnimationState animationDidStop:finished:]
#9 0x01ffa6cb in run_animation_callbacks
#10 0x01ffa589 in CA::timer_callback
#11 0x010f4fe3 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
#12 0x010f6594 in __CFRunLoopDoTimer
#13 0x01052cc9 in __CFRunLoopRun
#14 0x01052240 in CFRunLoopRunSpecific
#15 0x01052161 in CFRunLoopRunInMode
#16 0x01a48268 in GSEventRunModal
#17 0x01a4832d in GSEventRun
#18 0x002d442e in UIApplicationMain
#19 0x00002918 in main at main.m:14
EDIT: It seems that when I do not release my annotationViewController the application does not crash. I will keep playing with the application to see if this is right. Can anyone tell me if this might be right and if so, why? And when would I release it then?
- (void)mapView:(MKMapView *)aMapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
for(MyAnnotation* a in mapView.annotations) { // searching for chosen annotation
if(view.annotation == a) {
// set array from plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"Annotations" ofType:#"plist"];
NSMutableArray* anns = [[NSMutableArray alloc] initWithContentsOfFile:path];
AnnotationDetailViewController *annotationDetailViewController = [[AnnotationDetailViewController alloc] initWithNibName:#"AnnotationDetailViewController" bundle:nil];
annotationDetailViewController.ann = [anns objectAtIndex:[a.annId intValue]];
[self.navigationController pushViewController:annotationDetailViewController animated:YES];
[annotationDetailViewController release]; // this is the one that I think will correct the error
[anns release];
}
}
}
You should look for an ivar in AnnotationDetailViewController that you are under-retaining/over-releasing. I would suspect some UIView, perhaps an IBOutlet that you did not configure to retain, particularly if you also fail to set it to nil in viewDidUnload. I recommend you read Memory Management of Nib Objects if you haven't already.
It's difficult to debug this without the code, or more information about your variables, but that's where I would look given where it's crashing.
My program has crashed:
#0 0x3138cec0 in objc_msgSend
#1 0x0002bb6e in -[AdMobDelegateWrapper didYouNilOutYourDelegate:]
#2 0x0002c392 in -[AdMobDelegateWrapper publisherId]
#3 0x0001ab7e in -[AdMobAd buildParamsWithLastClickInfo:]
#4 0x0001b044 in -[AdMobAd requestAdFromServer]
#5 0x0001963c in -[AdMobAd browserIconsDidFinishLoading]
#6 0x0001a23e in -[AdMobAd downloadDidSucceed:]
#7 0x323fba14 in -[NSObject performSelector:withObject:]
#8 0x0002122e in -[AdMobURLDownload performRequest:]
#9 0x33731acc in -[NSThread main]
#10 0x336dfd14 in __NSThread__main__
#11 0x33ad8788 in _pthread_body
why?
I use 4.0 SDK and device's system version is iOS 3.1.3.
My codes is very simple that from examples which in "admob_iphone_sdk_20100818".
Ok, I found the solution.
I was almost there but not quite. The problem IS setting the delegate to nil, but the place was wrong.
This is how I solved it:
- (void)viewDidLoad {
[super viewDidLoad];
adMobAd = [AdMobView requestAdWithDelegate:self]; // start a new ad request
[adMobAd retain];
}
- (void)viewDidUnload {
//Nothing to do here
}
- (void)dealloc {
//THIS IS THE IMPORTANT STUFF
if (adMobAd != nil){
adMobAd.delegate = nil;
}
[adMobAd release];
[super dealloc];
}
Moving the "liberation" of the delegate to the dealloc block has fixed the problem for me.
Hope it helps!
I have a situation where I'm lazy loading images from the www.
It's a list of items, when one item is tapped, a detail view is pushed to a nav controller.
In that detail view the item has an image, which first is a default image, and I want to start loading it's image from a URL.
So what I do is create an object which once initialized detaches a new thread which in turn loads the content and afterwards notifies my view that the data is loaded:
// in MyLoader:
- (MyLoader *)initWithUrl:(NSURL *)url requester:(id)requester {
self.url = url;
self.requester = requester; // both are nonatomic, retain properties
[self performSelectorInBackground:#selector(loadIt) withObject:nil];
}
- (void)loadIt {
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSData *data = [NSData dataWithContentsOfURL:url];
[requester performSelectorOnMainThread:#selector(dataReady) withObject:data waitUntilDone:YES;
[arp release];
}
// in MyRequester:
- (void)somewhere {
MyLoader *loader = [[[MyLoader] alloc] initWithUrl:someUrl requester:self] autorelease];
// then I retain loader somewhere, it's more complicated but I have verified that it's properly retained.
}
A few notes:
First I thought there might be a problem with some of the variables. I put a breakpoint right before performSelectorOnMainThread and confirmed that data and requester were both OK.
Then I thought it was caused by passing the NSData across the threads, so I changed withObject:nil. It still crashes.
When I further investigated, the crash was very strange. I specified waitUntilDone:YES, I've placed a breakpoint in the requester's dataReady. But the performSelectorOnMainThread call returns (it reaches the breakpoint after it) while not reaching the breakpoint inside dataReady. BTW, - (void)dataReady:(NSData*)'s body for now only contains int x = 1; (to place a breakpoint on). Also, I've tried setting waitUntilDone:NO, it still crashes.
The selector isn't performed (the breakpoint is not reached), but the crash happens a short while after the call.
Does anyone have any idea what's wrong?
This is obvious, but just to be clear, if I just comment out the [requester performSelectorOnMainThread... part, it doesn't crash.
Also, here's a stack trace, but it's not helpful at all.
#0 0x00a71004 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ ()
#1 0x93436e3b in objc_exception_throw ()
#2 0x0028aca6 in __NSThreadPerformPerform ()
#3 0x00a098e1 in CFRunLoopRunSpecific ()
#4 0x00a08c48 in CFRunLoopRunInMode ()
#5 0x0005a78d in GSEventRunModal ()
#6 0x0005a852 in GSEventRun ()
#7 0x0168a003 in UIApplicationMain ()
#8 0x000028d4 in main (argc=1, argv=0xbffff100) at /Users/myName/Document/appName/main.m:14
You have:
[requester performSelectorOnMainThread:#selector(dataReady) withObject:data waitUntilDone:YES;
should be:
[requester performSelectorOnMainThread:#selector(dataReady:) withObject:data waitUntilDone:YES;
notice: #selector(dataReady:) (with colon)
Since you're passing an argument to the method, it's presumed data ready is defined something like:
- (void) dataReady:(NSData *)theData ...