Как управлять загрузкой в ​​память статических, лениво загруженных словарей и массивов - PullRequest
1 голос
/ 14 мая 2010

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

Большинство из них являются массивами строк, поэтому я могу конвертировать строки в константы NSInteger, которые можно использовать с операторами switch и т. Д.

Я мог бы просто воссоздавать массив / словарь при каждом вызове, но многие из этих функций используются интенсивно и / или в узких циклах.

Итак, я пытаюсь придумать шаблон, который является одновременно и быстродействующим, и непостоянным.

Если я храню информацию в виде списка, делает ли iphoneOS что-то умное с кэшированием при загрузке?

У вас есть другой метод, который может быть связан?

РЕДАКТИРОВАТЬ - ПРИМЕР ОТВЕТА

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

Сначала добавьте метод в NSObject через категорию.

- (void)autoreleaseOnLowMemory;

Теперь, когда я хочу создать статичный массив или словарь с отложенной загрузкой в ​​вспомогательной функции, я могу просто использовать следующий шаблон ...

- (id)someHelperFunction:(id)lookupKey {
    static NSDictionary *someLookupDictionary = nil;
    if (!someLookupDictionary) {
        someLookupDictionary = [[NSDictionary dictionaryWithObjects:X, Y, Z, nil] autoreleaseOnLowMemory];
    }
    return [someLookupDictionary objectForKey:lookupKey];
}

Теперь вместо того статического словаря, который дожил до конца программы, если у нас не хватит памяти, он будет освобожден и восстановлен только при необходимости снова. И да, в большом проекте, работающем на iphone, это может быть важно!

PS - Реализация autoreleaseOnLowMemory тривиальна. Просто создайте одноэлементный класс с методом, который берет объект и сохраняет его в наборе. Пусть этот синглтон прослушивает предупреждения о нехватке памяти, и, если он его получает, освобождает все объекты в этом наборе. Может также захотеть добавить функцию ручного отключения.

Ответы [ 2 ]

2 голосов
/ 14 мая 2010

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

0 голосов
/ 14 мая 2010

Если вы просто делаете строки, вы можете использовать массивы C.

id keys[] = { @"a" , @"b" , @"c" };
id values[] = { @"1" , @"2" , @"3" };

И если вам иногда требуется настоящий NSArray или NSDictionary из этого:

[NSArray arrayWithObjects:values count:3];
[NSDictionary dictionaryWithObjects:values forKeys:keys count:3];

Список будет включать в себя обращение к диску и разбор xml для каждой коллекции. Насколько я знаю, только NSUserDefaults кэшируются.

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