2010-09-15 4 views
1

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

+ (NSArray *)motivations 
{ 
    static NSArray *motivations = nil; 
    if (!motivations) 
    { 
     motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil]; 

    } 
    return motivations; 
} 

Редактировать 1 Спасибо Georg за ошибку.

ответ

2

Потому что это статический объект, поэтому система будет хранить указатель объекта до тех пор, пока приложение не будет завершено. Вы можете использовать этот способ для кэширования с помощью пусть вашей точки указателя на объект, который не является release или autorelease

Я рекомендую использовать этот подход, когда вы действительно хотите кэшировать некоторые данные в памяти (как правило, небольшие или больших изображения данных), что требуется много времени обработки процессора или ввода-вывода для генерации. Для небольших данных, таких как NSString, вы можете создавать новый массив и возвращаться каждый раз, когда вам нужно.

Edit для комментария: Есть 2 вещи, о imageNamed:

1/Вы не можете контролировать то, что кэшируется и то, что не кэшируются imageNamed:. Например, вы можете не кэшировать изображение с большим размером и использовать его только один раз.

2/imageNamed: не может использоваться для получения изображения из сети или папок в системе. Он будет загружаться только из вашего пакета

+2

Обратите внимание, что 'static 'влияет только на хранение указателей' motivations', время жизни массивов полностью не зависит от него. –

+0

Что касается изображения, под iPhone SDK, образ Named будет кэшировать изображение в системе. Нужно ли снова кэшировать изображение в коде? – AechoLiu

+0

есть 2 вещи: 1/вы не можете управлять imageNamed, что он будет кэшировать, а что нет. Вы определенно не хотите кэшировать изображение 3 или 10 МБ, например. 2/Вы не можете загрузить все изображение с помощью imageNamed, например, изображение находится в определенном пути в системе или в изображении, загруженном из Интернета – vodkhang

3

В примере, который вы показываете, есть ошибка - +arrayWithObjects: возвращает экземпляр с автореализацией, который будет уничтожен позже. Код был, вероятно, предназначены для:

motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil]; 

При том, что массив будет жить, пока приложение не завершается.

+0

ах да, я даже не замечаю эту ошибку – vodkhang

+0

^^ «Спасибо, я тоже этого не заметил. – AechoLiu

+1

Я подал это как ошибку на статическом анализаторе (анализатор должен улавливать автореализованные объекты, назначаемые в статические переменные): http://llvm.org/bugs/show_bug.cgi?id=4955 –

1

Поскольку это метод класса (обозначается символом + вместо объявления -), нет экземпляра, который будет выпущен. (Технически есть экземпляр объекта класса isa, я думаю («комментарий, если я ошибаюсь, пожалуйста, я не очень хорошо знаю внутреннюю работу), но не беспокойтесь об этом)

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

Lazy loading не позволяет создать его до тех пор, пока не будет вызван метод класса, поэтому он не тратит впустую память, пока вам это не понадобится.

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