Я пытаюсь выяснить, почему мое приложение дает сбой (RSS Reader), если я отправляю неправильный URL-адрес в NSXML Parser. Я получил EXC_BAD_ACCES
S. Итак, после некоторых поисков я обнаружил, что мне нужно использовать зомби. Поэтому я добавил в среду следующие аргументы:
CFZombieLevel = 3
NSMallocStaclLogging = YES
NSDeallocateZombies = NO
MallocStackLoggingNoCompact = YES
NSZombieEnabled = YES
NSDebugEnabled = YES
NSAutoreleaseFreedObjectCheckEnabled = YES
Я также добавил malloc_error_break
в качестве точки останова. Затем я добавил несколько других точек останова в графическом интерфейсе и нажал «Сборка и отладка». В консоли получаю следующее сообщение:
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
Если я наберу «shell 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? Я не могу найти код, который вызывает сбой моего приложения. Единственное, что я знаю, это то, что это должно быть сообщение responsesToSelector. Я добавил точку останова ко всем своим сообщениям responsesToSelector. Их бьют, но приложение не вылетает в этот момент. Я также пытался прокомментировать их, кроме одного, и это также приводит к сбою приложения. Тот, который не был закомментирован, не попал. Где у меня утечка памяти?
Следующая сбивающая с толку вещь заключается в том, что NSXML Parser продолжает свою работу, несмотря на вызов делегата parseErrorOccurred. После двухкратной ошибки приложение вылетает.
Почему Zombies in the Run с инструментом производительности отключен?
Изменить:
Сейчас воспользовался этой инструкцией (не могу постить. извините. защита от спама) у меня все заработало. Что это означает?
@Graham: В моем классе парсера я создаю экземпляр NSXMLParser
:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
...
NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:responseData];
[rssParser setDelegate:self];
...
[rssParser parse];
//[rssParser release];
}
Во время поиска ошибки я закомментировал метод выпуска. В настоящее время rssParser никогда не выпускается в классе парсера.
В моем классе RootViewController
я создаю свой парсер:
- (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];
}
}
Если я не выпущу его здесь, он не рухнет. Но для каждого alloc я должен делать релиз? Или я должен автоматически выпускать NSXMLParser
в connectionDidFinishLoading
?