【问题标题】:iPhone: Parsing multiple XML with NSXMLParser in background disturbing each otheriPhone:在后台使用 NSXMLParser 解析多个 XML,相互干扰
【发布时间】:2010-04-29 19:07:16
【问题描述】:

在 iPhone 上使用 NSXMLParser 解析 XML 时,我遇到了一个奇怪的问题。启动应用程序时,我想预加载 4 个表格视图,这些表格视图在后台由 RSS-Feed 填充。

当我一个一个地初始化表格视图时,加载、解析和显示所有工作就像一个魅力。但是当我尝试一次(同时)初始化所有视图时,XML-parser-instances 似乎相互干扰。不知何故,来自一个 XML-Feed 的数据被“广播”到其他不属于它们的 xml-parser 实例中。示例:有一个“团队成员”项目,带有“这是我的名字”。发生此错误时,会添加来自另一个 xml-feed 的字符串,即导致:“This is my name58”,其中 58 是其他视图中某物的图表位置。 “58”似乎在另一个实例上错过了。

在我看来,这个错误是由于 NSXMLParser-delegate 方法而发生的:

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

在这种情况下,“巧合”字节被附加到不属于它们的字符串中。

奇怪的是,每个 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];

这是后台任务之一,解析提要:

-(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-Parser 都有自己的唯一实例?

【问题讨论】:

  • currentStringValue = [[[NSMutableString alloc] initWithCapacity:50] retain]; 行错误。当您分配时,您将保留它。然后你再次保留它。你的意思是使用自动释放而不是保留?

标签: iphone background nsxmlparser multiple-instances


【解决方案1】:

您不应该从后台线程中更新 UI 元素(如 progressWheel)。 UI 更新应该在主线程上完成。

使用 -performSelectorOnMainThread:withObject:waitUntilDone: 在后台线程中更新 UI 元素。

【讨论】:

  • 哦,看来,这导致了我的应用程序的主要问题。将进行各种测试,但似乎这解决了问题。
【解决方案2】:

我发布了一个开源RSS/Atom Parser for iPhone,它使阅读和解析网络提要变得非常容易。

您可以将其设置为异步下载数据,也可以在后台线程中同步运行以收集Feed数据。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2012-10-19
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多