EXC_BAD_ACCESS в NSArray создал 3 строки перед сбоем - PullRequest
1 голос
/ 26 июня 2010

Я только начинаю свое первое «настоящее» приложение с какао.Обратите внимание, что это Mac, а не iPhone.

Эта функция вызывается, когда заканчивается моя асинхронная загрузка onemanga, и предназначена для анализа из нее списка манги NSArray.Я получаю NSArray от nodeForXPath и сохраняю его, чтобы убедиться, что он мой.(Также пытался сохранить его дважды, хе).К сожалению, попытка получить количество NSArray приводит к EXC_BAD_ACCESS.Точка сбоя отмечена двумя комментариями ниже.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Download Succeeded! Received %d bytes of data. Beginning Parse.",[mangaListData length]);
NSString* theQuery = [[NSString alloc]initWithString:@"//tr/td[@class=\"ch-subject\"]/text()"];
NSError *XMLError=nil;
NSError *XPathError=nil;
NSString* mangaListHTML;
NSString* fixedMangaListHTML;
mangaListHTML = [[NSString alloc] initWithData:mangaListData encoding:NSUTF8StringEncoding];
fixedMangaListHTML = [mangaListHTML stringByReplacingOccurrencesOfString:@" & " withString:@" & "];
NSXMLDocument* xmlDoc = [[NSXMLDocument alloc] initWithXMLString:fixedMangaListHTML
                                                        options:(NSXMLNodePreserveWhitespace|NSXMLNodePreserveCDATA)
                                                        error:&XMLError];
if (XMLError) {
    NSLog(@"XML Parse error: %@", XMLError);
    return;
};
[fixedMangaListHTML release];
[mangaListHTML release];
NSArray* results = [[xmlDoc nodesForXPath:theQuery error:&XPathError] retain];
if (XMLError) {
    NSLog(@"Parse error: %@", XPathError);
    return;
};
NSLog(@"Parsing complete. Manga List = ");
//CRASH HAPPENS HERE
NSLog(@"Size of array: %@", [results count]);
//CRASH HAPPENS ABOVE
for(NSXMLNode* title in results){
    NSLog(@"%@\n", title.description);
};
[XMLError release];
[XPathError release];
[connection release];
[mangaListData release];

}

Здесь вывод where в ГБД.(Я пока не знаю, как использовать gdb, поэтому любые команды, которые я мог бы запустить, чтобы получить больше информации, были бы высоко оценены.)

#0  0x00007fff855691d1 in objc_msgSend_vtable5 ()
#1  0x00007fff87e97207 in _NSDescriptionWithLocaleFunc ()
#2  0x00007fff8509ba2d in _CFStringAppendFormatAndArgumentsAux ()
#3  0x00007fff8509aead in _CFStringCreateWithFormatAndArgumentsAux ()
#4  0x00007fff85119f5f in _CFLogvEx ()
#5  0x00007fff87ef937f in NSLogv ()
#6  0x00007fff87ef9317 in NSLog ()
#7  0x0000000100002bca in -[TMMoneManga connectionDidFinishLoading:] (self=0x1001999f0, _cmd=0x7fff8803b5de, connection=0x1001689a0) at /Users/ripdog/Documents/TheMangaMachine/TMMoneManga.m:120
#8  0x00007fff87f16b8c in _NSURLConnectionDidFinishLoading ()
#9  0x00007fff8063f18e in URLConnectionClient::_clientDidFinishLoading ()
#10 0x00007fff806a4502 in URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload ()
#11 0x00007fff8062b8fb in URLConnectionClient::processEvents ()
#12 0x00007fff8062b6d8 in MultiplexerSource::perform ()
#13 0x00007fff850b6f21 in __CFRunLoopDoSources0 ()
#14 0x00007fff850b5119 in __CFRunLoopRun ()
#15 0x00007fff850b48df in CFRunLoopRunSpecific ()
#16 0x00007fff80b83ada in RunCurrentEventLoopInMode ()
#17 0x00007fff80b838df in ReceiveNextEventCommon ()
#18 0x00007fff80b83798 in BlockUntilNextEventMatchingListInMode ()
#19 0x00007fff8845fa2a in _DPSNextEvent ()
#20 0x00007fff8845f379 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#21 0x00007fff8842505b in -[NSApplication run] ()
#22 0x00007fff8841dd7c in NSApplicationMain ()
#23 0x00000001000017cd in main (argc=1, argv=0x7fff5fbff6c0) at /Users/ripdog/Documents/TheMangaMachine/main.m:13

Заранее большое спасибо.

Ответы [ 2 ]

3 голосов
/ 26 июня 2010

Проблема с вашей строкой формата. Спецификатор %@ будет отображать объект Objective-C, но [result count] является целым числом. Правильный спецификатор формата для целого числа - %d. Для справки: полный список спецификаторов формата строки Objective-C.

Ваш вопрос показал, что сбой происходит, когда вы пытаетесь получить [result count]. Однако, если вы посмотрите на стек вызовов, ваш код - это кадр № 7, а следующая функция в стеке (кадр № 6) - NSLog. Таким образом, это говорит о том, что проблема, вероятно, связана с вызовом NSLog, а не с [result count]. [result count] уже вернется до того, как поток управления войдет в NSLog.

Существуют различные методы отладки с помощью gdb. Так как вы отлаживаете сбой, вы в основном сосредоточитесь на проверке стека вызовов, переменных и памяти (в отличие от пошагового выполнения кода при его выполнении). Поэтому для такого рода отладки эти команды необходимы:

  • up Это перемещает «фокус» отладчика на один кадр стека вызовов. Допустим, вы хотите изучить переменные в вашей программе. Вы не можете видеть их в objc_msgSend_vtable5, где отладчик остановлен. Поэтому используйте up 7, чтобы перейти на семь кадров, чтобы вы смотрели на свой код.
  • down является противоположностью вверх. Часто вы хотите посмотреть, что привело к катастрофе, поэтому переход к вашему коду, а затем спуск, спуск, спуск - это способ понять, как разворачивается катастрофа. (Это не продвигает вас вперед и назад во времени , конечно.)
  • where Показывает вам часть стека вызовов. Вы уже обнаружили это. Мой единственный совет - вам часто нужно заботиться только о том, что находится на вершине стека вызовов. Вы можете использовать where n для печати первых n фреймов стека вызовов.
  • list Показывает исходный код «сфокусированного» кадра со стрелкой, указывающей точку выполнения. Так, например, up 7, за которым следует list, должны показать вам источник connectionDidFinishLoading с индикатором рядом с вызовом NSLog. Использование list часто более удобно, чем поиск кода в XCode, если вам просто нужно увидеть несколько строк окружающего контекста.
  • print Оценивает выражение и печатает его. Например, вы можете сделать print [results count], чтобы увидеть, что оценивает [results count]. Когда отладчик остановлен, а ваша программа находится в плохом состоянии, print может показаться смешным (он может действительно выполнять код). Поэтому часто простые выражения работают лучше.
  • info Информация может рассказать вам много вещей, но info locals действительно ценно. Он показывает локальные переменные, которые находятся в области видимости в «сфокусированном» фрейме отладчика.
1 голос
/ 26 июня 2010

count возвращает целое число, а не объект.Напечатайте его с помощью %d, а не %@.

(Если вы сделаете последнее, вы неявно преобразуете целое число в указатель на несуществующий объект в дебри того, кто знает где, и затем вызываете егоdescription метод.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...