【问题标题】:Trouble with Asynchronous Downloading UITableView异步下载UITableView的问题
【发布时间】:2011-05-01 23:44:52
【问题描述】:

我正在尝试为 UITableViewCell 异步下载图像,但它当前正在为每个单元格设置相同的图像。

请你告诉我我的代码的问题:

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

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

    SearchObject *so = (SearchObject *)[_tableData objectAtIndex:indexPath.row];
    cell.textLabel.text = [[[[so tweet] stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""] stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"] stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
    cell.detailTextLabel.text = [so fromUser];
    if (cell.imageView.image == nil) {
        NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:[so userProfileImageURL]]];
        NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
        [conn start];
    }
    if ([_cellImages count] > indexPath.row) {
        cell.imageView.image = [UIImage imageWithData:[_cellImages objectAtIndex:indexPath.row]];
    }
    return cell;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [_cellData appendData:data];
    [_cellImages addObject:_cellData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self.tableView reloadData];
}

【问题讨论】:

    标签: objective-c asynchronous uitableview nsurlconnection nsurlrequest


    【解决方案1】:

    您正在将下载的每个图像中的数据附加到同一个数据对象。因此,在最好的情况下,数据对象以图像#1 的数据结束,紧随其后的是图像#2 的数据,依此类推;图像解码器显然正在获取数据块中的第一张图像,然后忽略垃圾。您似乎也没有意识到 NSURLConnections 的 connection:didReceiveData: 不一定会按照连接开始的顺序被调用,connection:didReceiveData: 每个连接可以被调用零次或多次(如果您的图像超过几千字节),并且不能保证按顺序为表中的每个单元格调用tableView:cellForRowAtIndexPath:。所有这些都会彻底搞砸你的 _cellImages 数组。

    要正确执行此操作,您需要为每个连接有一个单独的 NSMutableData 实例,并且您只需将其添加到您的 _cellImages 数组中一次,并且在该行的正确索引处而不是在任意下一个可用的索引处指数。然后在connection:didReceiveData: 中,您需要找出要附加到的正确 NSMutableData 实例;这可以通过使用连接对象(使用valueWithNonretainedObject: 包装在NSValue 中)作为NSMutableDictionary 中的键,或使用objc_setAssociatedObject 将数据对象附加到连接对象,或者通过让自己成为一个处理所有为您管理 NSURLConnection 并在完成后将数据对象交给您。

    【讨论】:

      【解决方案2】:

      我不知道这是否会导致问题,但在您的 connection:didReceiveData: 方法中,您只是将图像数据附加到数组中;您应该以可以将其链接到应该显示的单元格的方式存储图像数据。一种方法是使用NSMutableArray填充一堆[NSNull]s,然后替换连接完成加载后,相应索引处的 null 值。

      此外,当连接尚未完成加载时,您将_cellData 附加到_cellImages 数组,您应该只在connection:didFinishLoading 方法中执行此操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-12
        • 1970-01-01
        • 2013-10-28
        • 2013-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多