iPhone: парсинг нескольких XML с NSXMLParser в фоновом режиме мешает друг другу - PullRequest
0 голосов
/ 29 апреля 2010

У меня странная проблема, когда дело доходит до разбора XML с NSXMLParser на iPhone. При запуске приложения я хочу предварительно загрузить 4 табличных представления, которые заполняются RSS-каналами в фоновом режиме.

Когда я запускаю просмотр таблиц один за другим, тогда загрузка, анализ и отображение всех работает как чудо. Но когда я пытаюсь запустить все представления одновременно (одновременно), то кажется, что экземпляры XML-парсера мешают друг другу . Каким-то образом данные из одного XML-канала «транслируются» в другие экземпляры XML-анализатора, где они не принадлежат. Пример: есть пункт "teammember" с надписью "Это мое имя". Когда возникает эта ошибка, добавляется строка из другого xml-фида, то есть, в результате: «Это мое имя58», где 58 - это позиция в чарте чего-либо из другого представления. «58», кажется, пропускает тогда в другом случае.

Мне кажется, что эта ошибка возникает из-за метода NSXMLParser-Delegate:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (!currentStringValue) {
        currentStringValue = [[NSMutableString alloc] initWithCapacity:50];
    }
    [currentStringValue appendString:string];   
}

В этом случае байты «по совпадению» добавляются к строкам, к которым они не принадлежат.

Странно то, что каждый экземпляр NSXMLParser уникален, имеет своих уникальных делегатов, которые присоединены к своему собственному ViewController. Каждый запрос синтаксического анализа порождает свою собственную фоновую задачу со своим собственным (также называемым также уникальным) Autorelease-pool.

Я называю 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-парсера есть свой уникальный экземпляр?

Ответы [ 2 ]

6 голосов
/ 29 апреля 2010

Вы не должны обновлять элементы пользовательского интерфейса (например, progressWheel) из фонового потока. Обновления пользовательского интерфейса должны выполняться в главном потоке.

Используйте -performSelectorOnMainThread:withObject:waitUntilDone: для обновления элементов пользовательского интерфейса из фонового потока.

0 голосов
/ 21 июля 2010

Я выпустил открытый исходный код RSS / Atom Parser для iPhone , и он делает чтение и анализ веб-каналов чрезвычайно простым.

Вы можете настроить его на асинхронную загрузку данных или синхронно запускать его в фоновом потоке для сбора данных канала.

Надеюсь, это поможет!

...