1

CocoaLibSpotify ライブラリを使用して、Spotify 検索結果のアルバム アートを読み込みます。

Instrumentsはリークを報告しておらず、静的分析も役に立たず、アルバムアートのロードを追跡するすべてのコードを手動で確認しましたが、数百の結果をロードした後、アプリは100MB以上を消費しますメモリとクラッシュの。

CocoaLibSpotify は画像のキャッシュをメモリに保持していると思いますが、キャッシュを無効にする方法は見つかりませんでした。「flushCaches」メソッドがあり、メモリ警告が出るたびに呼び出していましたが、効果がありません。

ここでは、アルバム アートを読み込むために使用しているものを示します。配列内のすべての SPImage オブジェクトへの参照を保持しているため、テーブル ビューの行を提供するときにそれらを使用できます。

[self sendRequestToURL: @"http://ws.spotify.com/search/1/track.json" withParams: @{@"q": spotifySearchBar.text} usingMethod: @"GET" completionHandler: ^(id result, NSError *error) {
    //after the search completes, re-enable the search button, replace the searchResults, and
    //  request the result table to reload the data
    spotifySearchBar.userInteractionEnabled = YES;
    [searchBar endEditing: YES];
    [searchResults release];
    int resultLength = [[result objectForKey: @"tracks"] count] < 100 ? [[result objectForKey: @"tracks"] count] : 100;
    searchResults = [[[result objectForKey: @"tracks"] subarrayWithRange: NSMakeRange(0, resultLength)] retain];
    for(int i = 0; i < 100; i++) {
        [albumArtCache replaceObjectAtIndex: i withObject: [NSNull null]];
    }
    for(NSDictionary *trackDict in searchResults) {
        NSString *trackURI = [trackDict objectForKey: @"href"];
        [SPTrack trackForTrackURL: [NSURL URLWithString: trackURI] inSession: session callback: ^(SPTrack *track) {
            [SPAsyncLoading waitUntilLoaded: track timeout: kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedItems, NSArray *notLoadedItems) {
                if(track == nil) return;
                [SPAsyncLoading waitUntilLoaded: track.album timeout: kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedItems, NSArray *notLoadedItems) {
                    if(track.album == nil) return;
                    [SPAsyncLoading waitUntilLoaded: track.album.largeCover timeout: kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedItems, NSArray *notLoadedItems) {
                        if(track.album.largeCover == nil) return;
                        if(![searchResults containsObject: trackDict]) {
                            NSLog(@"new search was performed, discarding loaded result");
                            return;
                        } else{
                            [albumArtCache replaceObjectAtIndex: [searchResults indexOfObject: trackDict] withObject: track.album.largeCover];
                            [resultTableView reloadRowsAtIndexPaths: @[[NSIndexPath indexPathForRow: [searchResults indexOfObject: trackDict] inSection: 0]] withRowAnimation: UITableViewRowAnimationAutomatic];
                        }
                    }];
                }];
            }];
        }];
    }
    [resultTableView reloadData];
}];

テーブル ビュー セルの読み込みを処理するコードは次のとおりです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: @"artistCell"];
    if(cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: @"artistCell"] autorelease];
    }
    cell.textLabel.text = [[searchResults objectAtIndex: indexPath.row] objectForKey: @"name"];
    cell.detailTextLabel.text = [[[[searchResults objectAtIndex: indexPath.row] objectForKey: @"artists"] objectAtIndex: 0] objectForKey: @"name"];

    if([albumArtCache objectAtIndex: indexPath.row] != [NSNull null]) {
        cell.imageView.image =  ((SPImage *)[albumArtCache objectAtIndex: indexPath.row]).image;
    } else{
        cell.imageView.image = nil;
    }

    return cell;
}

何が問題なのか本当にわかりません。どんな援助でも大歓迎です。

4

1 に答える 1