0

这个问题可能听起来很傻,但我似乎无法理解异步下载、解析和显示数据的想法。有很多关于异步解析的文章,我也看了很多,但是我没有找到任何关于正确显示异步下载数据的文章。我有一个使用解析器来解析 rss 提要的应用程序。起初我使用了一个同步请求,尽管应用程序在等待数据时有点滞后(显然),但一切都运行良好。xml 解析器如下所示:

#import "XMLAsynchronousParser.h"
@implementation XMLAsynchronousParser
@synthesize itemList;
-(void)startParse:(NSString *)url{
parsing = YES;
receivedData = [[NSMutableData alloc] init];
itemList = [[NSMutableArray alloc] init];
errorParsing = NO;

NSLog(@"PARSING from url:\n%@",url);
NSString *agentString = @"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1";

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];

[request setValue:agentString forHTTPHeaderField:@"User-Agent"];

NSURLConnection *urlConnection = [NSURLConnection connectionWithRequest:request delegate:self];
[urlConnection start];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[receivedData appendData:data];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"Connection did finish loading");
    rssParser = [[NSXMLParser alloc] initWithData:receivedData];
    [rssParser setDelegate:self];
    [rssParser parse];

    parsing = NO;
}


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    NSLog(@"Asynchronous parsing did end with error:\n%@",[error description]);
}

#pragma Mark - parsing methods

- (void)parserDidStartDocument:(NSXMLParser *)parser{
    NSLog(@"FILE found and parsing started.");
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{

    currentElement = [elementName copy];
    elementValue = [[NSMutableString alloc] init];
    if([currentElement isEqualToString:@"item"]){
        item = [[NSMutableDictionary alloc] init];
    }
}

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

    if([elementName isEqualToString:@"item"]){
        [itemList addObject:[item copy]];
    }else{
        [item setObject:elementValue forKey:elementName];
    }
}

@end

我在这样的awakefromnib方法中初始化解析器:self.xmlParser = [[XMLAsynchronousParser alloc] init];

刷新后调用start parse方法:

- (void)dropViewDidBeginRefreshing{
    NSArray *filters = [[NSArray alloc] init];
    NSMutableArray *itemList = [[NSMutableArray alloc] init];

    filters = [self.dataController selectSelectedFilters];

    for (BazosAgentFilter *filter in filters) {
        NSString *url = [self.dataController createURLfromFilter:filter];
        [self.xmlParser startParse:url];

        for (NSDictionary *item in self.xmlParser.itemList) {
            NSString *title = [item objectForKey:@"title"];
            NSString *description = [item objectForKey:@"description"];
            NSString *pubdate = [item objectForKey:@"pubDate"];
            NSString *link = [item objectForKey:@"link"];
            BazosAgentItem *bazosItem = [[BazosAgentItem alloc] initWithTitle:title
                                                                  description:description
                                                                         link:link
                                                                      pubdate:pubdate
                                                                     filterId:filter.filter_id];
            [self.dataController addBazosAgentItem:bazosItem];
        }

        [itemList addObjectsFromArray:[self.dataController selectItemsFromDatabaseWithFilterId:[filter.filter_id integerValue]]];
    }
    self.itemList = itemList;
    [self.tableView reloadData];
    [self.refreshControl endRefreshing];
}

cellForRowAtIndexPath方法如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"###cell for row!");

    NSString *cellIdentifier = @"BazosItemCell";
    ItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    BazosAgentItem *item = [self.itemList objectAtIndex:indexPath.row];
    NSLog(@"ITEM LINK: %@",item.link);

    NSString *itemTitle = item.title;
    NSString *itemID = [self parseItemID:item.link];
    NSString *itemIDpostfix = [itemID substringFromIndex:(itemID.length-3)];
    NSString *itemImageString = [NSString stringWithFormat:@"http://www.bazos.sk/img/1/%@/%@.jpg",itemIDpostfix,itemID];
    NSURL *itemImageUrl = [NSURL URLWithString:itemImageString];

    [cell.itemImage setImageWithURL:itemImageUrl];
    cell.itemImage.contentMode = UIViewContentModeScaleAspectFit;

    cell.firstLabel.text = itemTitle;

    [cell sizeToFit];
    return cell;
    }

问题是,在我使用 Refresh 方法后 UITableView 没有显示任何内容。我错过了什么吗?

4

1 回答 1

2

我没有阅读您的所有代码,但通常正确的解决方案如下。

1)当你有完整的数据块时,将一个块分派到主线程。向表格询问其可见单元格,如果数据会更改其中任何一个,则更新您的数据模型(很可能是可变数组),然后重新加载表格。

2)如果数据不可见,只需将其存储在数组中。当用户滚动表格时,您可以使用数据。

于 2013-05-22T11:46:55.290 回答