ReplysToSelector send to the freed object

I am trying to find out why my application (RSS Reader) crashes if I submit the wrong URL to NSXML Parser. I got EXC_BAD_ACCES S. So after some searching, I found that I had to use zombies. So I added the following arguments on Wednesday:

 CFZombieLevel = 3 NSMallocStaclLogging = YES NSDeallocateZombies = NO MallocStackLoggingNoCompact = YES NSZombieEnabled = YES NSDebugEnabled = YES NSAutoreleaseFreedObjectCheckEnabled = YES 

I also added malloc_error_break as a breakpoint. Then I added some other breakpoints in the GUI and clicked “Build and Debug”. In the console, I get the following message:

2010-08-28 18:41:49.761 RssReader[2850:207] *** -[XMLParser respondsToSelector:]: message sent to deallocated instance 0x59708e0

Sometimes I also get the following message: wait_fences: failed to receive reply: 10004003

If I type "shell malloc_history 2850 0x59708e0", I get the following:

 ... ALLOC 0x5970870-0x59709d7 [size=360]: thread_a0aaa500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] | -[UIApplication ... ---- FREE 0x5970870-0x59709d7 [size=360]: thread_a0aaa500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication ... ALLOC 0x59708e0-0x597090f [size=48]: thread_a0aaa500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] | -[UIApplication ... Binary Images: 0x1000 - 0x6ff3 +RssReader ??? (???) <6EBB16BC-2BCE-CA3E-C76E-F0B078995E2D> /Users/svp/Library/Application Support/iPhone Simulator/4.0.1/Applications/AF4CE7CA-88B6-44D4-92A1-F634DE7B9072/RssReader.app/RssReader 0xe000 - 0x1cfff3 +Foundation 751.32.0 (compatibility 300.0.0) <18F9E1F7-27C6-2B64-5B9D-BAD16EE5227A> ... 

What does it mean? How do I know which object is 0x59708e0? I cannot find the code that causes my application to crash. The only thing I know is that this should be a RespondsToSelector message. I have added a breakpoint to all my RespondsToSelector posts. They get hit, but the application does not crash at that moment. I also tried to comment them out, except for one, and also the application crashes. One that was not commented out did not hit. Where is my memory leak?

The next incomprehensible thing is that NSXML Parser continues its work, despite the fact that the delegate parseErrorOccurn is called. After two times an error is issued, the application crashes.

Why are Zombies in the Run disabled with the Peformance Tool?

Edit:

Now I used this instruction (I can’t post. Sorry. Spam protection) I got this working. What does this mean?

@Graham: In my parser class, I have an NSXMLParser instance of NSXMLParser :

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { ... NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:responseData]; [rssParser setDelegate:self]; ... [rssParser parse]; //[rssParser release]; } 

While searching for an error, I commented out the release method. RssParser is currently never released in the analyzer class.

In my RootViewController class RootViewController I RootViewController my parser:

 - (void)loadData { if (newsItems == nil) { [activityIndicator startAnimating]; XMLParser *rssParser = [[XMLParser alloc] init]; [rssParser parseRssFeed:@"http://feeds2.feedburner.com/TheMdnShowtest" withDelegate:self]; [rssParser release]; rssParser = nil; } else { [self.tableView reloadData]; } } 

If I do not release it here, it will not collapse. But for each highlighted should I make a release? Or should I NSXMLParser release NSXMLParser in connectionDidFinishLoading ?

+4
source share
4 answers

In RootViewController.h, I declared the rssParser property:

 @class XMLParser; @interface RootViewController : UITableViewController { ... XMLParser *rssParser; } ... @property (retain, nonatomic) XMLParser *rssParser; @end 

In RootViewController.m I have a method called errorOccurred:

 - (void)errorOccurred { [rssParser release]; rssParser = nil; if ([activityIndicator isAnimating]) { [activityIndicator stopAnimating]; } } 

In my XMLParser.m file, I call errorOccurred two times:

 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { ... if ([_delegate respondsToSelector:@selector(errorOccurred)]) [_delegate errorOccurred]; else { [NSException raise:NSInternalInconsistencyException format:@"Delegate doesn't respond to errorOccurred:"]; } } 

To learn how _delegate is declared, check out the tutorial http://www.cocoadevblog.com/iphone-tutorial-creating-a-rss-feed-reader . This is an id variable and has its own setter and getter method (you can also declare it as a property, which I think). Second time:

 - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { ... if ([_delegate respondsToSelector:@selector(errorOccurred)]) [_delegate errorOccurred]; else { [NSException raise:NSInternalInconsistencyException format:@"Delegate doesn't respond to errorOccurred:"]; } } 

The output of my rssParser variables is as follows:

In loadData in RootViewController.m I never release it. Unfortunately, this will happen if I do this in loadData. It is issued only in case of an error (see above) or in the dealloc method. But I think this should work fine, as it is declared as a property.

 - (void)loadData { if (newsItems == nil) { [activityIndicator startAnimating]; self.rssParser = [[XMLParser alloc] init]; [rssParser parseRssFeed:@"http://www.wrongurl.com/wrongrss.xml" withDelegate:self]; } else { [self.tableView reloadData]; } } 

In XMLParser.m, I release it after the parse method:

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { ... NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:responseData]; [rssParser setDelegate:self]; [rssParser parse]; [rssParser release]; rssParser = nil; } 

Note that the names of the two variables are the same (rssParser), but they are different. In RootViewController, I create an instance of XMLParser in XMLParser.m as well. I am creating an instance of NSXMLParser.

So, I think that I will stay on this until I have a new error, or one of you will explain to me why this is bad.

+1
source

A zombie shuts down when you use it with memory leaks, as all zombies will be flagged as leaks. To launch the Zombie tool, you can go to the Tool menu and make File> Create and select the Zombie tool yourself, so the program will stop if the zombie receives a message and you will be given a link in a small pop-up a window to this zombie object and its history

+1
source

Somewhere you highlight XMLParser. Take a look at this code. You don't turn it off, right?

Somewhere he is freed ... is it appropriated to the property? Let's look at this property definition.

The responsesToSelector: method is later called, but it can be any method. The fact is that your XMLParser was released before your intention.

+1
source

You also have rssParser, the same instance variable that you set for release here ...

 - (void)errorOccurred { [rssParser release]; rssParser = nil; if ([activityIndicator isAnimating]) { [activityIndicator stopAnimating]; } } 

... released in your dealloc method? This will result in a double release and therefore EXEC_BAD_ACCESS.

+1
source

All Articles