【问题标题】:detachNewThreadSelector crashes the app randomlydetachNewThreadSelector 随机使应用程序崩溃
【发布时间】:2011-05-09 14:49:28
【问题描述】:

我正在开发一个 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

【问题讨论】:

  • 当你崩溃时你从控制台得到什么日志?
  • 另外,打开断点运行并告诉我们应用程序崩溃时您在调试器中看到的堆栈跟踪,以便我们找出原因。我敢打赌它在您未在此处显示的 NSXMLParser 委托回调之一中,但如果没有更多信息,我们无法诊断此问题。
  • 实际上我应该解释整个场景。我正在使用 stringWithFormat 将我得到的所有提要附加到一个字符串中。当我此时观察分配时,它们超过了 34 MB,但应用程序没有'不会在那里崩溃。当我打开应用程序时。应用程序开始搜索提要并且当它在网络视图中加载提要时分配的内存超过 30 MB。但应用程序不会崩溃。然后当我导航时在应用程序中,解析器再次进入 parserDidStartDocument: 然后应用程序抛出一个错误的访问异常,这是我得到的唯一日志。此时应用程序崩溃。
  • 为什么会出现这种糟糕的访问和额外的内存使用?为什么它第二次进入 parserDidStartDocument: ?我猜线程处理有问题。但是什么?
  • 我已编辑问题以添加控制台日志

标签: iphone objective-c rss threadpool pool


【解决方案1】:

我不确定,但我猜该方法的参数会在某个时候发布。您能否确保该 URL 存在于方法 parseXMLFileAtURL

【讨论】:

  • 该 url 存在,我可以在浏览器中访问它。我也从中获取提要。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    //你可以使用方法,如果你不必更新UserInterface会更安全

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

    如果 UserInterface 也需要更新,您可以先在后台解析数据并使用方法更新 ui。

    [self performSelectorOnMainThread:@selector(myUpdateUI) withObject:nil waitUntilDone:YES];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-19
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      • 1970-01-01
      相关资源
      最近更新 更多