0

I developed a simple RSS fetcher application that parses an XML RSS feed from a programmer-provided website and displays the articles in the Master View Controller and the UIWebView in a Detail View Controller. I custom set-up a personal server to render the RSS article selected in the master table view (for certain reasons) as a PDF. However, this obviously takes some time on the server end, unless the selected table view cell has already been rendered as a PDF on the server end. My server and blog don't talk to one another (and can't, for other reasons), so I can't pre-render the PDFs as I create the blog posts. The PDF render must be done from the application itself.

I decided to use Grand Central Dispatch to create a separate thread to talk to the server and render the PDFs before the user can select an arbitrary cell to see the post. Here is the code I used to create the queue.

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

...and the code I used to create the new thread...

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

...here is my cachePDFRequests method that is called in the block request...

- (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];
    }
}

Note: cacheView is a UIWebView that is not on any UI...it is just an ivar of my Master VC class.

So, when I run the dispatch_async() function in -[viewDidLoad], it runs the -[cachePDFRequests] method and the for() loop inside of it, then throws SIGABRT on my newly-created thread. Please ask any questions as necessary. Let me know if I need to include any code that I haven't already provided.

Here is a picture of the SIGABRT error that appears whenever I run the GCD thread:

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

Thanks in advance!

P.S. I used to run cacheView = [[UIWebView alloc] init]; in an if() loop if the cacheView was set to nil...that used to throw the SIGABRT error. Now, it has no references to code in my Master View Controller after I removed that line.

EDIT: Here is the code for what the feeds mutable array is containing:

- (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]];

}
4

1 回答 1

3

看起来您正在feeds越界访问。NSArray如果您尝试使用超出其范围的索引访问它,则会引发异常,而这正是回溯所指示的。这是循环索引从 0 开始的数组的正确方法:

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

作为旁注,没有if()循环这样的东西。

于 2013-07-16T05:48:12.627 回答