我试图找出为什么我的应用程序崩溃(RSS阅读器),如果我发送错误的URL到NSXML解析器。我得到了EXC_BAD_ACCES
S.所以在一些搜索之后,我发现我必须使用僵尸。所以我在环境中添加了以下参数:respondsToSelector发送到释放对象
CFZombieLevel = 3
NSMallocStaclLogging = YES
NSDeallocateZombies = NO
MallocStackLoggingNoCompact = YES
NSZombieEnabled = YES
NSDebugEnabled = YES
NSAutoreleaseFreedObjectCheckEnabled = YES
我还加了malloc_error_break
作为断点。然后我在GUI中添加了一些其他断点,并按下了Build and Debug。在控制台中我得到以下信息:
2010-08-28 18:41:49.761 RssReader[2850:207] *** -[XMLParser respondsToSelector:]: message sent to deallocated instance 0x59708e0
有时候,我也得到了以下信息: wait_fences: failed to receive reply: 10004003
如果我输入“壳malloc_history 2850 0x59708e0”我得到如下:
...
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>
...
这是什么意思?我如何知道0x59708e0是哪个对象?我无法找到导致我的应用崩溃的代码。我唯一知道的是它应该是一个respondsToSelector消息。我为所有的respondsToSelector消息添加了一个断点。他们被击中,但应用程序崩溃在那一刻。我也试图评论他们,除了一个,也让应用程序崩溃。没有被注释掉的那个没有被击中。我在哪里有内存泄漏?
下一个令人困惑的事情是NSXML解析器继续它的工作,尽管调用了parseErrorOccurred委托。在两次抛出错误之后,应用程序崩溃。
为什么僵尸在运行与性能工具被禁用?
编辑:
现在我用这个指令(无法发布对不起防止垃圾邮件。)我得到了这个工作。这是结果:http://yfrog.com/mrzombievp那么这是什么意思?
@Graham: 在我的分析器类我实例NSXMLParser
:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
...
NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:responseData];
[rssParser setDelegate:self];
...
[rssParser parse];
//[rssParser release];
}
在我搜索的错误,我注释掉的释放方法。目前rssParser从未在解析器类中获得发布。
在我RootViewController
I类实例化我的解析器:
- (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];
}
}
如果我没有在这里释放它,它不会崩溃。但是对于每个分配我都必须做一个释放?或者我应该自动发布在connectionDidFinishLoading
?
感谢您的提示!我在阅读时意识到这一点http://www.corbinstreehouse.com/blog/2007/10/instruments-on-leopard-how-to-debug-those-random-crashes-in-your-cocoa-app/ 我并不知道Instruments是独立程序,不属于Xcode。不过,我不明白他们为什么会提供该菜单条目,如果它不能使用。 – testing 2010-08-29 09:53:34