У меня проблема, я не могу понять. Сделали тонны поиска и попробовали около 50 различных вариаций, до сих пор нет кубиков. Вот моя дилемма.NSData память не освобождается - ARC
У меня есть 3 метода. Один вызывается, когда мой объект PageView загружается, другой вызывается всякий раз, когда пользователь вносит изменения, а последний вызывается всякий раз, когда пользователь покидает страницу.
Первый метод:
- (void)captureInitialLinesTexture {
@autoreleasepool {
self.initialLinesTextureCaptured = TRUE;
GLubyte *buffer =(GLubyte *) malloc (1024 * 1024 * 4 * sizeof(GLubyte));
glPixelStorei(GL_PACK_ALIGNMENT,1) ;
glReadPixels(0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glBindTexture(GL_TEXTURE_2D, [pageTexture name]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
NSData __autoreleasing *tempData = [NSData dataWithBytes:buffer length:1024*1024*4*sizeof(GLubyte)];
if (textureData == nil) {
textureData = [self.pageController.notebookDoc newTextureInPage:self.page];
}
[pageTextures addObject:tempData];
if ([pageTextures count] > 5) {
[pageTextures removeObjectAtIndex:0];
}
textureData.textureData = tempData;
textureData.page = self.page;
self.page.texture = textureData;
self.page.lastLineId = [NSNumber numberWithInt:self.pageController.newLineId - 1];
[self.pageController saveNotebookWithUndo:FALSE];
free((GLubyte*)buffer);
}
}
Второй метод:
-(void)capturePageTexture {
@autoreleasepool {
GLubyte *buffer =(GLubyte *) malloc (1024 * 1024 * 4 * sizeof(GLubyte));
glPixelStorei(GL_PACK_ALIGNMENT,1) ;
glReadPixels(0, 0, 1024, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
NSData __autoreleasing *tempData = [NSData dataWithBytes:buffer length:1024*1024*4*sizeof(GLubyte)];
[pageTextures addObject:tempData];
if ([pageTextures count] > 5) {
[pageTextures removeObjectAtIndex:0];
}
free((GLubyte*)buffer);
}
}
И последний способ:
-(void)attemptInstantPageTextureCapture {
if ([pageTextures count] > 0) {
self.page.texture.textureData = [pageTextures lastObject];
self.page.lastLineId = [NSNumber numberWithInt:self.pageController.newLineId - 1];
[self.pageController saveNotebookWithUndo:FALSE];
}
[pageTextures removeAllObjects];
pageTextures = [NSMutableArray arrayWithCapacity:0];
}
Моя проблема с этими переменными NSData * TempData. По какой-то причине один из них случайно зависает после того, как мой PageView ушел (обнаружен через Allocations Instruments).
Если я загружаю PageView, загорается captureInitialLinesTexture. Затем я могу добавить много штрихов для пера и capturePageTexture после каждого удара, сохраняя до 5 переменных NSData в именах NSMutableArray pageTextures. Когда я покидаю PageView, NSMutableArray опустеет.
Теперь вот он получает удар головой в стену. Распределение NSData всегда одного размера, в этом случае 4 МБ. Когда страница загружается, у меня есть 1 4 мб. Если я сделаю штрихи пера, я смогу получить еще до 5. Затем, когда я покидаю PageView, до 5 из 4-х распределений (NSData) освобождаются, но я всегда получаю левый с 1. Если я затем перейду к Call Tree на инструментах, он случайным образом скажет его из этого первого метода или второго метод. Почему у него нет проблем с сбросом 5 NSData, которые хранятся в массиве, но почему-то 1 NSData где-то оставлен в живых. Кроме того, эта тайна NSData происходит из любого метода случайным образом.
Как я уже сказал, я искал и искал и не могу найти решение этой проблемы. 4MB памяти, очевидно, огромна, поэтому любые утечки такого типа будут убивать приложение с течением времени.
Выделение из одной попытки:
Дерева вызовов для этой попытки:
распределения для еще одной попытки:
Дерева вызовов для других попыток:
Тот же самый точный код срабатывает каждый раз, и каждый раз, когда это случайно, NSData остается в живых. Кто-нибудь знает, что я делаю неправильно? переменными «page» и «textureData» являются NSManagedObjects, если вам интересно.Насколько вещей, которые я пробовал:
Alloc на объектах NSData затем вызвать initWithBytes: длина:
initWithBytesNoCopy: Длина: - не звонить бесплатно ((GLubyte *) буфер);
initWithBytesNoCopy: Length: freeWhenDone: - не вызывал бесплатный ((GLubyte *) буфер);
NSData метод класса версия выше двух попыток
не используется @autoreleasepool
не используется для __autoreleasing вара декларации
делает NSMutableArray pageTextures свойства страницуПоказать
настройки страницуПоказать к nil до того, как он выскочит из стека NavigationController
, итерации через изменяемый массив pageTextures с использованием __strong и установка всех NSData на nil или null.
Как уже упоминалось выше, все это происходит в классе PageView, который является одним из многих в своем роде в пределах PageViewController, который выталкивается, а затем удаляется с навигационного контроллера. После того, как элемент просмотра PageViewController (только супервизл просмотра) выведен из навигационного стека, одно случайное распределение NSData все еще сохраняется.
Любые предложения вообще были бы чрезвычайно оценены! Что касается основных элементов данных, упомянутых выше, код работает точно так, как планировалось. Единственная проблема заключается в том, что sneaky live NSData distribution ... :(
Да, удаление __autoreleasing не влияет. Такая же проблема сохраняется. Но спасибо за то, что вы пролили свет на ключевое слово. – Kevin
Использование инструментов, которые вы можете распечатать, получает информацию о размещении, сохранении и выпуске объекта, как показано в этом сообщении, -> http://www.markj.net/iphone-memory-debug-nszombie/. Посмотрите, можете ли вы получить это info, потому что это должно многое помочь. – borrrden