У меня проблема с существующим приложением для 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 один за другим.
Кажется сумасшедшим, я знаю.Есть лучшее решение существует?