detachNewThreadSelector随机导致应用程序崩溃

4

我正在开发一款iPhone应用程序,其中我正在提取RSS订阅并解析它们。我的代码如下:

 - (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSLog(@"in view did appear");

    if ([stories count] == 0) {
        NSString * path = @"http://www.shire.com/shireplc/rss.jsp";

        //[self parseXMLFileAtURL:path];
        //[self performSelectorInBackground:@selector(parseXMLFileAtURL:) withObject:path];
        NSLog(@"internet is %d",[self checkInternet]);
        if([self checkInternet]==1)
        [NSThread detachNewThreadSelector:@selector(parseXMLFileAtURL:) 
                              toTarget:self withObject:path];

}
}

 - (void)parseXMLFileAtURL:(NSString *)URL
  { 
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  stories = [[NSMutableArray alloc] init];

  //you must then convert the path to a proper NSURL or it won't work
  NSURL *xmlURL = [NSURL URLWithString:URL];

  // here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
  // this may be necessary only for the toolchain
  rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];

  // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];

// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];

[rssParser parse];

 [pool release];

}

请问有人可以告诉我错在哪里吗? 我的日志如下: 日志: [切换到线程 12803] [切换到线程 12035] 2011-05-10 11:31:30.932 年度报告[454:490b] 找到文件并开始解析 [切换到线程 14339] 2011-05-10 11:32:04.742 年度报告[454:640b] 找到文件并开始解析 [切换到线程 13827] [切换到线程 13827] 程序收到信号:“EXC_BAD_ACCESS”。

gdb stack trace at 'putpkt: write failed':
0   gdb-arm-apple-darwin                0x0019026b remote_backtrace_self + 54

3
你在崩溃时从控制台获得了哪些日志? - lxt
1
此外,请在断点模式下运行,并告诉我们当应用程序崩溃时调试器中看到的堆栈跟踪,以便我们可以确定原因。我敢打赌问题出现在您未在此处展示的某个NSXMLParser委托回调函数中,但是如果没有更多信息,我们无法诊断此问题。 - Brad Larson
实际上我应该解释整个情况。我正在使用stringWithFormat将所有获取到的Feed追加到一个字符串中。当我观察到这时的内存分配情况时,它们超过了34MB,但是应用程序并没有在那里崩溃。当我打开应用程序时,应用程序开始搜索Feeds,并在加载webview中的Feeds时分配内存超过30MB。但是程序并没有崩溃。然后当我导航到应用程序中时,解析器再次进入parserDidStartDocument:此时应用程序抛出了一个错误访问异常,这是我得到的唯一日志。此时应用程序崩溃。 - Yogi
为什么会出现访问错误和额外的内存使用?为什么它会第二次进入parserDidStartDocument:方法?我猜测是线程处理方面出了一些问题。但具体是什么呢? - Yogi
我已编辑问题以添加控制台日志。 - Yogi
3个回答

0
最后,我使用了一个标志来检查视图是否出现(通过在viewdidAppear中设置标志为真),如果视图没有出现,则不运行线程函数。这解决了问题!!!

0

我不确定,但我猜测该方法的参数在某个时刻被释放了。你能确保URL出现在parseXMLFileAtURL方法中吗?


该网址存在且我能够在浏览器中访问它。我也可以从中获取到数据源。 - Yogi

0

// 如果您不需要更新用户界面,可以使用这种更安全的方法

 [self performSelectorInBackground:@selector(parseXMLFileAtURL:) withObject:path];

如果需要更新用户界面,您可以先在后台解析数据,然后使用该方法更新UI。
[self performSelectorOnMainThread:@selector(myUpdateUI) withObject:nil waitUntilDone:YES];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接