0

私は自分のプロジェクトに GCD を実装しようとしましたが、これは XML からデータを取得することを示しています。コードの一部) 両方の文字列と同じ GCD を実装しようとしても何も表示されません。何が起こっているのかわかりませんが、プロジェクトを実行すると不明な例外が発生します。GCD を実装する方法を知りたいです。コードのコメント部分で、imageViewに画像を表示できるようになります。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


    static NSString *CellIdentifier = @"CustomCell";

    dataFileHolder *currentData = [[xmlParser listPopulated] objectAtIndex:indexPath.row];
    CustomCellXMLClass *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];



    if(cell == nil) {
        cell = [[CustomCellXMLClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellXMLSample" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    }

    myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(myQueue, ^{
        NSString *nameLabel = [currentData nameOfCat];
        NSString *dataToCacheLabel = [myCache objectForKey:nameLabel];
        if(nameLabel != nil){
            dataToCacheLabel = [NSString stringWithString:nameLabel];
                if (dataToCacheLabel != nil) {
                    [myCache setObject:dataToCacheLabel forKey:nameLabel];
                    dispatch_async(dispatch_get_main_queue(), ^{
                    [cell.nameLabel setText:dataToCacheLabel];
                 });
                }
        }



        NSString *detailLabel = [currentData descriptionOfCat];
        NSString *stringToCache = [myCache objectForKey:detailLabel];
        if (detailLabel != nil) {
            stringToCache = [NSString stringWithString:detailLabel];
                if (stringToCache != nil) {
                    [myCache setObject:stringToCache forKey:detailLabel];
                    dispatch_async(dispatch_get_main_queue(), ^{

                    [cell.detailLabel setText:stringToCache];
                   });
                }
        }

//        NSString *imageURL = [currentData imageLink];
//        NSData *dataToCache;
//            if (imageURL != nil) {
//                
//                dataToCache = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
//                if (dataToCache != nil) {
//                    
//                    [myCache setObject:dataToCache forKey:imageURL];
//                    [cell.imageShow setImage:[UIImage imageWithData:dataToCache]];
//                    
//                }
//                else {
//                    
//                    NSURL *imageURL = [NSURL URLWithString:@"http://i178.photobucket.com/albums/w255/ace003_album/190579604m.jpg"];
//                    dataToCache = [NSData dataWithContentsOfURL:imageURL];
//                    [myCache setObject:dataToCache forKey:imageURL];
//                    [cell.imageShow setImage:[UIImage imageWithData:dataToCache]];
//                }
//            
//            }
        [self.activityIndicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES];

    });
         return cell;

}
4

1 に答える 1

3

最初の 2 つの場合と同様に、セルを更新する部分をメイン スレッドにディスパッチする必要があります。この部分:dispatch_async(dispatch_get_main_queue(),...)おそらく次のようになります。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CustomCell";
    static NSInteger usageCount = 0;

    dataFileHolder *currentData = [[xmlParser listPopulated] objectAtIndex:indexPath.row];
    CustomCellXMLClass *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil) {
        cell = [[CustomCellXMLClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellXMLSample" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    // Give it a new tag every time, so we can tell if this is "our" use of the cell
    cell.tag = ++usageCount;

    myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(myQueue, ^{
        NSString *nameLabel = [currentData nameOfCat];
        NSString *dataToCacheLabel = [myCache objectForKey:nameLabel];
        if(nameLabel != nil){
            dataToCacheLabel = [NSString stringWithString:nameLabel];
            if (dataToCacheLabel != nil) {
                [myCache setObject:dataToCacheLabel forKey:nameLabel];
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (cell.superview && usageCount == cell.tag)
                    {
                        [cell.nameLabel setText:dataToCacheLabel];
                    }
                });
            }
        }

        NSString *detailLabel = [currentData descriptionOfCat];
        NSString *stringToCache = [myCache objectForKey:detailLabel];
        if (detailLabel != nil) {
            stringToCache = [NSString stringWithString:detailLabel];
            if (stringToCache != nil) {
                [myCache setObject:stringToCache forKey:detailLabel];
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (cell.superview && usageCount == cell.tag)
                    {
                        [cell.detailLabel setText:stringToCache];
                    }
                });
            }
        }

        NSURL *fallbackImageURL = [NSURL URLWithString:@"http://i178.photobucket.com/albums/w255/ace003_album/190579604m.jpg"];
        NSString *imageURL = [currentData imageLink];
        NSArray* urls = imageURL ? @[ imageURL, fallbackImageURL ] : @[ fallbackImageURL ];
        for (NSURL* url in urls)
        {
            UIImage* cachedImage = [myCache objectForKey: url];
            if (!cachedImage)
            {
                NSData* imageData = [NSData dataWithContentsOfURL:url];
                cachedImage = [UIImage imageWithData:dataToCache];
                [myCache setObject:cachedImage forKey:url];
            }

            if (cachedImage)
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (cell.superview && usageCount == cell.tag)
                    {
                        [cell.imageShow setImage: uiImage];
                    }
                });
                break;
            }
        }
    });
    return cell;
}

長期的にはdataWithContentsOfURL:、データが完全に受信されるのを待っているバックグラウンド スレッドをブロックする代わりに、多くの非同期読み込みアプローチのいずれかを検討する必要があります。しかし、それはここでは二次的な問題であり、あなたが尋ねたものではありません.

編集: @Rob のコメント用に編集。フェッチする前に事前にキャッシュされた画像のキャッシュをチェックし、再利用されたセルや非表示のセルに値を書き込まないようにします (他の目的で使用していないと仮定しますtag)。ただし、実際には、非同期の画像ダウンロード マネージャーを使用してください。

于 2013-08-21T17:14:44.560 に答える