GCD创建的线程在完成阻止消息后抛出中止

时间:2013-07-16 04:37:55

标签: iphone objective-c objective-c-blocks grand-central-dispatch sigabrt

我开发了一个简单的RSS fetcher应用程序,它从程序员提供的网站解析XML RSS提要,并在详细视图控制器中显示主视图控制器和UIWebView中的文章。我自定义设置个人服务器以将主表视图中选择的RSS文章(出于某些原因)呈现为PDF。但是,这显然需要一些时间在服务器端,除非所选的表视图单元格已在服务器端呈现为PDF。我的服务器和博客不会互相交谈(由于其他原因,不能),因此我无法在创建博客文章时预呈现PDF。 PDF渲染必须从应用程序本身完成。

我决定使用Grand Central Dispatch创建一个单独的线程来与服务器通信并在用户可以选择任意单元格以查看帖子之前呈现PDF。这是我用来创建队列的代码。

dispatch_queue_t networkQueue = dispatch_queue_create("com.company.networkQueue", NULL);

...以及我用来创建新线程的代码......

dispatch_async(networkQueue, ^{ [self cachePDFRequests]; });

...这是我在block请求中调用的cachePDFRequests方法...

- (void) cachePDFRequests {
    NSURL *myURL;
    NSString *cacheUrl;
    NSURLRequest *request;

    for (int i = 0; i <= feeds.count; i++) {

        cacheUrl = [feeds[i] objectForKey:@"link"];
        cacheUrl = [cacheUrl stringByReplacingOccurrencesOfString:@" " withString:@""];
        cacheUrl = [cacheUrl stringByReplacingOccurrencesOfString:@"\n" withString:@""];

        NSString *fullUrl = [NSString stringWithFormat:@"http://myserver.com/render.php?url=%@", cacheUrl];

        myURL = [NSURL URLWithString:fullUrl];
        request = [NSURLRequest requestWithURL:myURL];

        [cacheView loadRequest:request];
    }
}

注意:cacheView是一个不在任何UI上的UIWebView ...它只是我的Master VC类的ivar。

因此,当我在 - [viewDidLoad]中运行dispatch_async()函数时,它运行 - [cachePDFRequests]方法和其中的for()循环,然后在我新创建的线程上抛出SIGABRT。如有必要,请提出任何问题。如果我需要包含我尚未提供的任何代码,请告诉我。

以下是每当我运行GCD线程时出现的SIGABRT错误图片:

http://tinypic.com/r/1038zd1/5

提前致谢!

P.S。我曾经在if()循环中运行cacheView = [[UIWebView alloc] init];,如果cacheView设置为nil ...用于抛出SIGABRT错误。现在,删除该行后,它在我的主视图控制器中没有引用代码。

编辑:这是feed可变数组包含的代码:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

if ([elementName isEqualToString:@"item"]) {

    [item setObject:title forKey:@"title"];
    [item setObject:link forKey:@"link"];

    [feeds addObject:[item copy]];

}

1 个答案:

答案 0 :(得分:3)

看起来您正在访问feeds越界。如果您尝试使用超出其边界的索引访问它,NSArray将抛出异常,这正是回溯指示的内容。这是循环遍历索引从0开始的数组的正确方法:

for (int i = 0; i < feeds.count; i++) // Notice that it uses < instead of <= as comparator

作为旁注,不存在if()循环。