iPhone:在背景中解析多个XML与NSXMLParser相互干扰

nod*_*ond 0 iphone background multiple-instances nsxmlparser

当我在iPhone上使用NSXMLParser解析XML时,我有一个奇怪的问题.启动应用程序时,我想预先加载4个表视图,这些视图在后台由RSS-Feeds填充.

当我逐个启动表视图时,而不是加载,解析和显示所有的工作,如魅力.但是当我尝试一次(同时)初始化所有视图时,看起来XML-parser-instances互相干扰.不知何故,来自一个XML-Feed的数据被"广播"到其他不属于的xml-parser实例中.示例:有一个"团队成员"项目,"这是我的名字".当这个错误发生时,添加了另一个xml-feed的字符串,即导致:"这是我的名字58",其中58是来自另一个视图的图表位置.在另一个例子中,"58"似乎错过了.

在我看来,由于NSXMLParser委托方法,这个错误发生了:

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

在这种情况下,"通过巧合"字节被附加到不属于它们的字符串.

奇怪的是,NSXMLParser的每个实例都是唯一的,有自己独特的委托,附加到自己的ViewController.每个解析请求产生它自己的后台任务,它有自己的(也是唯一命名的)自动释放池.

我在ViewController中调用NSXMLParser:

// 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];
Run Code Online (Sandbox Code Playgroud)

这是解析feed的后台任务之一:

- (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]; 
Run Code Online (Sandbox Code Playgroud)

}

什么可能导致这个问题?我是否以正确的方式调用了后台任务?为什么这个bug接近,因为每个XML-Parser都有自己独特的实例?

Ale*_*lds 6

您不应该progressWheel在后台线程内更新UI元素(例如).UI更新应该在主线程上完成.

用于-performSelectorOnMainThread:withObject:waitUntilDone:从后台线程中更新UI元素.