0

StackOverflow の友人や同僚のプログラマー、

私の RootViewController (ビュー上の flowerTableView) は、タイトル、サブタイトル、およびイメージ サムネイル (カメラ ロールから読み込まれる) を含むセルを表示する必要があります。私が推測する非常に基本的なテーブル。

すべてのコンテンツは「コア データ」に保存されますが、画像はカメラ ロールへの imagePath として保存されます。例:flower.imagePath = assets-library://asset/asset.JPG?id=1000000002&ext

下部のコードを使用すると、すべてがスムーズに実行されるはずですが、そうではありません。アプリを起動すると、タイトルとサブタイトルは表示されますが、画像は表示されません。詳細ビューを表示するセルを押すと、再びメイン ビューに戻り、この特定のセルの画像が表示されます。

「すべて表示」を押すと、次のコードを実行するツールバーのボタン

NSFetchRequest *fetchRequest = [[self fetchedResultsController] fetchRequest];
[fetchRequest setPredicate:nil];

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
[self.flowerTableView reloadData];

テーブルをリロードすると、すべての美しい花が表示されます。

最初に花が飾られなかったのはなぜですか。これはキャッシングの問題ですか?

このコードをデバッグすると、「この関数が実行された後にこのデバッグ文字列がログに記録されました」という文字列が、「すべて表示」を押した後ではなく、アプリの起動時にテーブルをロードした後にログに記録されました。セルが表示された後にセルに添付されたため、表示されません。

「すべて表示」を押すと、意図したとおりに同じ行が印刷されます

ここで何が起こっているのか、さらに良いことに、これを機能させるためにコードで何を変更すればよいかを誰かが教えてくれることを願っています。私は今立ち往生しています...

助けてくれてありがとう!エドウィン

:::コード:::

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

    Flower *flower = [fetchedResultsController_ objectAtIndexPath:indexPath];

    static NSString *CellIdentifier = @"Cell";

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

    // Configure the cell...

    // Display the image if one is defined
    if (flower.imagePath && ![flower.imagePath isEqualToString:@""])
    {
        // Should hold image after executing the resultBlock
       __block UIImage *image = nil;

        ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *asset)
        {
            NSLog(@"This debug string was logged after this function was done");
            image = [[UIImage imageWithCGImage:[asset thumbnail]] retain];
        };

        ALAssetsLibraryAccessFailureBlock failureBlock  = ^(NSError *error)
        {
            NSLog(@"Unresolved error: %@, %@", error, [error localizedDescription]);
        };

        [assetsLibrary_ assetForURL:[NSURL URLWithString:flower.imagePath] 
                        resultBlock:resultBlock
                       failureBlock:failureBlock];

        [cell.imageView setImage:image];
    }

    return cell;
}
4

2 に答える 2

2

-[ALAssetsLibrary assetForURL:resultBlock:failureBlock] は非同期で実行されます。これは、呼び出しが tableView:cellForRowAtIndexPath: メソッドですぐに返されることを意味します。アセットが実際に読み込まれる前に、セルがテーブル ビューに表示されます。

あなたがする必要があるのは、結果ブロックのセルの画像を設定することです。このようなもの:

if (flower.imagePath && ![flower.imagePath isEqualToString:@""])
{
    ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *asset)
    {
        NSLog(@"This debug string was logged after this function was done");
        [cell.imageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];

        //this line is needed to display the image when it is loaded asynchronously, otherwise image will not be shown as stated in comments
        [cell setNeedsLayout]; 

    };

    ALAssetsLibraryAccessFailureBlock failureBlock  = ^(NSError *error)
    {
        NSLog(@"Unresolved error: %@, %@", error, [error localizedDescription]);
    };

    [assetsLibrary_ assetForURL:[NSURL URLWithString:flower.imagePath] 
                    resultBlock:resultBlock
                   failureBlock:failureBlock];
}
于 2011-09-29T18:08:11.430 に答える
-1

仲間のオーバーフロー主義者は、次の解決策を提案させてくれました:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath でセルを作成するのではなく

テーブルに表示する UITableViewCells (cellForRowAtIndexPath メソッドで作成したものと同じもの) が入力された NSMutableArray を作成し、関連する UITableViewCell (NSMutableArray のオブジェクトになります) を cellForRowAtIndexPath メソッドで返すだけです。

このように、cellForRowAtIndexPath メソッドは、既にロードされており、表示する準備ができているセルを表示します。

于 2011-09-29T19:11:32.403 に答える