iOS 5 + iPad 1 = меньше доступной памяти - PullRequest
2 голосов
/ 28 октября 2011

У меня проблема с существующим приложением для iPad.Это довольно сложное приложение, написанное частично на родном языке (загрузка, локальное кэширование и т. Д.), Частично с использованием Sencha Touch для пользовательского интерфейса (без PhoneGap).

Приложение отлично работает как на iPad 1, так и на iPad 2 под iOS4.Но с публичным выпуском iOS 5 появится проблема для пользователей iPad 1.Приложение вылетает через несколько секунд работы.Некоторые парни пишут , что вместо 78 доступно только 30 мегабайт памяти для iPad 1 под iOS 5. А другой черный ящик - UIWebView.Никто не знает его внутренних ограничений.

У меня есть несколько идей, как оптимизировать JavaScript и HTML.Например, я оптимизировал структуру и сократил выделение памяти в скриптах, как мог.Я также заменил теги IMG на DIV + background-image.Но сбои остаются.

Ниже приведено безумное решение проблемы.

Решение

Есть предупреждения о памяти, но я не могу выпустить ни что-то родное, ничто-нибудь внутри JavaScript, подумал я.Поэтому я решил сделать смешную вещь - выделить фиктивный массив в несколько мегабайт и освободить его по предупреждению памяти.Это глупо, но это работает для меня: я мог бы выделить до 100 мегабайт ОЗУ при запуске с простой функцией malloc ()

// Member variable
void* dummy;

// - (void)init    
dummy = malloc(100000000L);

и освободить ее с помощью free () при запросе системы.

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

    if (dummy) {
        free(dummy);
        dummy = nil;
    }
}

На этот раз приложение работает дольше.Пока все хорошо ... Следующий шаг - сделать возможным повторное освобождение памяти.

// Member variable
NSMutableArray* _memoryWorkaround;

// - (void)init
int chunkCount = 100;
int chunkSize = 1L * 1024L * 1024L; // 1 megabyte

_memoryWorkaround = [[NSMutableArray alloc] initWithCapacity:chunkCount];

for (int i = 0; i < chunkCount; i++)
    [_memoryWorkaround addObject:[NSValue valueWithPointer:malloc(chunkSize)]];

Вот оно - 100 блоков памяти на 1 мегабайт.Эти параметры подлежат пересмотру.

Теперь мы можем высвободить столько памяти, сколько необходимо:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

    if ([_memoryWorkaround count]) {
        NSValue* val = [_memoryWorkaround objectAtIndex:0];
        free([val pointerValue]);
        [_memoryWorkaround removeObject:val];
    }
}

При свободном выходе:

- (void)dealloc {
    if ([_memoryWorkaround count]) {
        for (NSValue* val in _memoryWorkaround)
            free([val pointerValue]);
        [_memoryWorkaround removeAllObjects];
    }
    [_memoryWorkaround release];
    [super dealloc];
}

Последнеесделать - это заполнить буфер обратно в chunkCount с помощью NSTimer один за другим.

Кажется сумасшедшим, я знаю.Есть лучшее решение существует?

...