У меня странная проблема, когда дело доходит до синтаксического анализа XML с помощью NSXMLParser на iPhone. При запуске приложения я хочу предварительно загрузить 4 табличных представления, которые заполняются RSS-потоками в фоновом режиме.
Когда я инициирую просмотр таблиц один за другим, загрузка, синтаксический анализ и отображение все работает как шарм. Но когда я пытаюсь запустить все представление сразу (одновременно), мне кажется, что экземпляры XML-парсера мешают друг другу. Каким-то образом данные из одного XML-фида «транслируются» в другие экземпляры xml-парсера, которым они не принадлежат. Пример: есть элемент «член команды» с надписью «Это мое имя». Когда возникает эта ошибка, добавляется строка из другого xml-фида, то есть приводит к: «Это мое имя58», где 58 - позиция на диаграмме для чего-то из другого представления. «58», кажется, не хватает тогда на другом экземпляре.
Мне кажется, что эта ошибка возникает из-за метода делегата NSXMLParser:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!currentStringValue) {
currentStringValue = [[NSMutableString alloc] initWithCapacity:50];
}
[currentStringValue appendString:string];
}
В этом случае «по совпадению» байты добавляются к строкам, которым они не принадлежат.
Странно то, что каждый экземпляр NSXMLParser уникален, имеет свои собственные уникальные делегаты, которые прикреплены к их собственному ViewController. Каждый запрос на синтаксический анализ порождает свою собственную фоновую задачу со своим собственным (также уникальным по имени) пулом автозапуска.
Я вызываю NSXMLParser в ViewController следующим образом:
// prepare XML saving and parsing
currentStringValue = [[[NSMutableString alloc] initWithCapacity:50] retain];
charts = [[NSMutableArray alloc] init];
NSURL *url = [[NSURL alloc] initWithString:@"http://(SOME XML URL)"];
xmlParser = [[[NSXMLParser alloc] initWithContentsOfURL:url] retain];
//Set delegate
[xmlParser setDelegate:self];
//loading indicator
progressWheel = [[[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(150.0,170.0,20.0,20.0)] autorelease];
progressWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
[self.view addSubview:progressWheel];
[progressWheel startAnimating];
// start loading and parsing the xml-feed in the background
//[self performSelectorInBackground:@selector(parse:) withObject:xmlParser]; -> I also tried this
[NSThread detachNewThreadSelector:@selector(parse:) toTarget:self withObject:xmlParser];
А это одна из фоновых задач по разбору ленты:
- (void) parse: (NSXMLParser *) myParser {
NSAutoreleasePool *schedulePool = [[NSAutoreleasePool alloc] init];
BOOL success = [myParser parse];
if(success) {
NSLog(@"No Errors. xmlParser got: %@", myParser);
(POST-PROCESSING DETAILS OF THE DATA RETURNED)
[self.tableView reloadData];
} else {
NSLog(@"Couldn't initalize XMLparser");
}
[progressWheel stopAnimating];
[schedulePool drain];
[myParser release];
}
Что могло вызвать эту проблему? Правильно ли я вызываю фоновую задачу? Почему приближается эта ошибка, если у каждого XML-парсера есть свой уникальный экземпляр?
currentStringValue = [[[NSMutableString alloc] initWithCapacity:50] retain];
неверна. Когда вы распределяете, вы сохраняете это. Тогда вы снова его сохраняете. Вы хотите использовать автозапуск вместо сохранения? - person lucius   schedule 29.04.2010