Массивный утечек памяти - CocoaLibSpotify

64
7

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

В инструментах нет утечек, и статический анализ также не помогает, и я вручную просмотрел весь свой код, который касается отслеживания загрузки обложек альбомов, но после загрузки нескольких сотен результатов приложение потребляет более 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;
}

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

спросил(а) 2021-01-19T17:45:07+03:00 6 месяцев назад
1
Решение
63

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

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

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

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

ответил(а) 2021-01-19T17:45:07+03:00 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема