2013-08-30 3 views
1

Я использую библиотеку CocoaLibSpotify для загрузки обложек альбомов для поиска результатов Spotify.Массивный утечек памяти - CocoaLibSpotify

Инструменты не содержат утечек, и статический анализ также не помогает, и я вручную просмотрел весь мой код, который касается отслеживания загрузки обложек альбомов, однако после загрузки нескольких сотен результатов приложение потребляет более 100 МБ памяти и сбоев.

Я считаю, что 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; 
} 

Я действительно не знаю, что происходит. Будем очень благодарны любой помощи.

ответ

1

Прежде всего, вы должны использовать SPSearch, а не веб-API для поиска.

Причина, по которой приборы не обнаруживают утечку памяти, заключается в том, что ее нет - CocoaLibSpotify кэширует альбомы и изображения изнутри по соображениям производительности. В результате также будут загружены загруженные обложки альбомов.

Теперь загрузка сотен изображений 1024x1024 в память, очевидно, закончится плохо. Простым способом устранения проблемы было бы не загружать изображение самого большого размера - обычно это не требуется для представления таблицы с разрешением 1024x1024 пикселей.

В противном случае вы можете изменить CocoaLibSpotify, чтобы иметь возможность выгружать изображения. Самый простой способ сделать это, вероятно, добавить метод SPImage, что в принципе делает противоположность -startLoading - а именно, установка image свойства nil, в hasStartedLoading и loaded свойства NO и вызов sp_image_release на spImage собственности перед установкой, что NULL ,

Смежные вопросы