Как работает поведение сохранения данных NSImage? - PullRequest
3 голосов
/ 05 апреля 2011

У меня есть метод, который постоянно загружает новые данные изображения из Интернета.Всякий раз, когда поступают все данные для изображения, оно пересылается делегату следующим образом:

NSImage *img = [[NSImage alloc] initWithData:dataDownloadedFromWeb];
if([[self delegate] respondsToSelector:@selector(imageArrived:)]) {
    [[self delegate] imageArrived:img];
} 
[img release]; 

В imageArrived: данные изображения присваиваются NSImageView:

- (void)imageArrived:(NSImage *)img
{
    [imageView1 setImage:img];
}

Это хорошо работает, изображение отображается и обновляется с каждым новым циклом загрузки.Я профилировал свою заявку с помощью инструментов, чтобы убедиться, что нет утечек - она ​​не показывает утечек.Однако, если я проверю с помощью Instruments 'Activity Monitor, я смогу увидеть, как мое приложение захватывает все больше и больше памяти со временем, примерно увеличиваясь в размере загруженных изображений.Если я опущу [imageView1 setImage:img], использование памяти останется постоянным.Мой вопрос: как это происходит?Мой код течет?Как экземпляр NSImage в NSImageView определяет, когда следует выпускать свои данные?Спасибо за ваши ответы!

1 Ответ

1 голос
/ 13 апреля 2011

Когда вы выполняете initWithData, счетчик сохраняемых данных data увеличивается на единицу.Освобождение изображения не меняет счет сохранения данных.Вот куда уходит ваша память.Структуры изображений приходят и уходят, как вы хотите, но фрагменты данных накапливаются.

сохраните дескриптор данных отдельно и очистите его после удаления nsimage, и все должно быть хорошо:

(id) olddata = 0; // global or something with persistence
your_routine
{
    (id) newdata = dataDownloadedFromWeb;
    NSImage *img = [[NSImage alloc] initWithData: newdata];
    if([[self delegate] respondsToSelector:@selector(imageArrived:)])
    {
        [[self delegate] imageArrived:img];
    }
    [img release];
    if (olddata) [olddata release];
    olddata = newdata;
}

cleanup
{
    if (olddata) [olddata release];
    olddata = 0;
}
...