UITableView& A的异步下载问题ASIHTTP

时间:2012-02-23 00:41:17

标签: iphone uitableview asynchronous asihttprequest

我尝试使用ASIHTTP在我的UITableView上加载一些图像,但是我遇到了一些问题。首先,我读了一个xml文件(用tbxml),然后在字典中保存标题,图像路径和描述,然后在数组中,为了解析我使用这个代码:

- (void)loadUnknownXML {    
    // Load and parse the books.xml file
    tbxml = [TBXML tbxmlWithURL:[NSURL URLWithString:@"http://www.xxx.com"]];

    // If TBXML found a root node, process element and iterate all children
    if (tbxml.rootXMLElement){
        [self traverseElement:tbxml.rootXMLElement];
    }
}

- (void) traverseElement:(TBXMLElement *)element {

    TBXMLElement *child = element->firstChild;
    TBXMLElement *items = [TBXML childElementNamed:@"item" parentElement:child];

    do{
        if (items->firstChild) {

            TBXMLElement *titolo = [TBXML childElementNamed:@"title" parentElement:items];
            TBXMLElement *descrizione = [TBXML childElementNamed:@"description" parentElement:items];
            //NSLog(@"Titolo: %@ \n Descrizione: %@",[TBXML textForElement:titolo],[TBXML textForElement:descrizione]);

            self.elemento = [[NSMutableDictionary alloc] init];
            [self.elemento setObject:[TBXML textForElement:titolo] forKey:@"Titolo"];

            NSString *indirizzoImmagine = [TBXML textForElement:descrizione];
            NSRange rangeSRC = [indirizzoImmagine rangeOfString:@"src=\""];
            indirizzoImmagine = [indirizzoImmagine substringFromIndex:NSMaxRange(rangeSRC)];
            NSRange rangeAMP = [indirizzoImmagine rangeOfString:@"&amp"];
            NSRange rangeWidth = [indirizzoImmagine rangeOfString:@"&width"];
            if (rangeAMP.location != NSNotFound) {
                indirizzoImmagine = [indirizzoImmagine substringToIndex:NSMaxRange(rangeAMP)];
            }
            else if (rangeWidth.location != NSNotFound){
                indirizzoImmagine = [indirizzoImmagine substringToIndex:NSMaxRange(rangeWidth)];
            }        
            indirizzoImmagine = [indirizzoImmagine stringByReplacingOccurrencesOfString:@"&amp" withString:@""];
            indirizzoImmagine = [indirizzoImmagine stringByReplacingOccurrencesOfString:@"&width" withString:@""];



            [self.elemento setObject:indirizzoImmagine forKey:@"IndirizzoImmagine"];

            [self.elemento setObject:[TBXML textForElement:descrizione] forKey:@"Descrizione"];
            [self.array addObject:self.elemento];
        }

    }
    while ((items=items->nextSibling));

}

然后我开始下载

- (void) loadURL:(NSURL *)url index:(int)index
{

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];


    ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];

    [request setDownloadCache:cache];
    [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
    [request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];

    [cache setStoragePath:@"/Users/kikko/kikko/xxx"];

    request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 
                        [NSNumber numberWithInt:index], @"index",
                        url, @"url", nil];


    [request setDelegate:self];
    [request startAsynchronous];

}


    - (void)requestFinished:(ASIHTTPRequest *)request
    {

        int index = [[request.userInfo valueForKey:@"index"] intValue];

    ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];  
    [cache setStoragePath:@"/Users/kikko/kikko/xxx"];

    [request.userInfo valueForKey:@"url"];

    if ([cache cachedResponseDataForURL:[request.userInfo valueForKey:@"url"]]==nil) {

        NSLog(@"%@",[request.userInfo valueForKey:@"url"]);

        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:index inSection:0];
        NSArray* rows = [NSArray arrayWithObjects:indexPath, nil];
        [table reloadRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationNone];

    }

    }

    - (void)requestFailed:(ASIHTTPRequest *)request
    {
        NSError *error = [request error];
        NSLog(@"Error: %@",error);

    }

最后我将图像放在cell.imageview

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.array.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 50;
}

-(NSString *) stringByStrippingHTML:(NSString *)stringa {

    NSRange r;

    NSString *str = stringa;
    while ((r = [str rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
        str = [str stringByReplacingCharactersInRange:r withString:@""];
    return str; 
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"ItemCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}

elemento = [array objectAtIndex:indexPath.row];

NSURL *indirizzoImmagine = [NSURL URLWithString:[elemento objectForKey:@"IndirizzoImmagine"]];

[self loadURL:indirizzoImmagine index:indexPath.row];

ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];
[cache setStoragePath:@"/Users/kikko/kikko/xxx"];

dataImmagine = [cache cachedResponseDataForURL:indirizzoImmagine];

[cell.imageView setImage:[UIImage imageWithData:dataImmagine]];

cell.textLabel.text = [elemento objectForKey:@"Titolo"];

return cell;

}

2 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题,但对现有代码的最微创方法是将userinfo字典附加到请求对象。

在您的遍历方法中执行以下操作:

//...
while ((items=items->nextSibling));
for (int i = 0; i < [self.array count]; i++)
{
    [arrayData addObject:[NSNull null]];
}

然后在您的请求方法中执行此操作

- (void) loadURL:(NSURL *)url index:(int)index
{

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

    [request setDownloadCache:[ASIDownloadCache sharedCache]];
    [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
    [request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];

    request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:index], @"index", nil];

    [request setDelegate:self];
    [request startAsynchronous];

}


- (void)requestFinished:(ASIHTTPRequest *)request
{

    NSData *responseData = [request responseData];
    int index = [[request.userInfo valueForKey:@"index"] intValue];
    [arrayData replaceObjectAtIndex:index withObject:responseData];



    //EDIT below:
    NSIndexPath* indexPath = [NSIndexPath indexPathForRow:index inSection:0];
    NSArray* rows = [NSArray arrayWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationNone];
}

在您的手机代码中,执行以下操作:

if ([arrayData objecAtIndex:indexPath.row] != [NSNull null]) {
         UIImage *img = [UIImage imageWithData:[self.arrayData objectAtIndex:indexPath.row]];
         imageView.image = img;
         [cell.imageView setImage:img];        
    } else {

        imageView.image = nil;
    }

答案 1 :(得分:0)

最好的例子是Apple下载和显示图像Asyn

https://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html

同时我也会检查你的代码