Утечка памяти приводит к сбою моего приложения камеры GPUImage

У меня возникают проблемы при попытке сделать более 1 фотографии. Приложение становится медленным, а затем вылетает из-за нескольких предупреждений о памяти. Я использую библиотеку Брэда GPUImage. Вот несколько методов, в которых я его использую:

//создание вида камеры

- (IBAction)photoFromCamera
{
    imageView = [[GPUImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    imageView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:imageView];

    stillCamera = [[GPUImageStillCamera alloc] init];

    stillCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
    //stillCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;

    filter = [[GPUImageFilter alloc] init];
    [filter prepareForImageCapture];
    [stillCamera addTarget:filter];

    [stillCamera addTarget:imageView];

    [filter addTarget:imageView];
    [stillCamera startCameraCapture];

    UIButton * shotButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    shotButton.frame = CGRectMake(137, 361, 46, 30);
    [shotButton setTitle:@"Take!" forState:UIControlStateNormal];
    [shotButton addTarget:self action:@selector(shotAction:) forControlEvents:UIControlEventTouchUpInside];

    [imageView addSubview:shotButton];

    UIButton * cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    cancelButton.frame = CGRectMake(10, 80, 55, 40);
    [cancelButton setTitle:@"cancel" forState:UIControlStateNormal];
    [cancelButton addTarget:self action:@selector(cancelAction) forControlEvents:UIControlEventTouchUpInside];

    [imageView addSubview:cancelButton];
}

// Действие «сделать фото»

-(void)shotAction:(UIImagePickerController *)photoPicker{
    [stillCamera capturePhotoAsPNGProcessedUpToFilter:filter withCompletionHandler:^(NSData *processedPNG, NSError *error) {
        self.saveButton.enabled = YES;
        self.filterButton.enabled = YES;
        self.cropButton.enabled = YES;

        originalFirstImage = [UIImage imageWithData:processedPNG];

        [self.selectedImageView setImage:originalFirstImage];
    }];

    [imageView removeFromSuperview];
}

здесь что-то не так? Я использую ARC, что-то не выходит? Спасибо за ваши комментарии.

РЕДАКТИРОВАТЬ: ошибка: Завершено из-за нехватки памяти


person Vergmort    schedule 16.01.2014    source источник
comment
Я вижу одну вещь, вы захватываете себя в блоке. И блок захватит его как сильную ссылку, создаст цикл сохранения. Это должен быть слабый указатель на себя.   -  person Adnan Aftab    schedule 16.01.2014
comment
@C_X в моем заголовке они у меня такие: property(nonatomic, weak) IBOutlet UIBarButtonItem *filterButton; property(nonatomic, weak) IBOutlet UIBarButtonItem *saveButton; property (nonatomic, weak) IBOutlet UIButton *cropButton; должен ли я изменить их на переменные класса?   -  person Vergmort    schedule 16.01.2014
comment
если вы обращаетесь к себе, он сохранит себя, а сам сохранит блок, я думаю, что это цикл сохранения... доступ к себе как к слабому указателю   -  person Adnan Aftab    schedule 16.01.2014


Ответы (1)


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

__weak typeof(self) weakSelf = self;

и используйте этот weakSelf в блоке.

ИЗМЕНИТЬ

Библиотека GPUImage также сообщает о некоторых проблемах с утечкой памяти, читайте этот форум

person Adnan Aftab    schedule 16.01.2014
comment
Ошибка продолжает появляться, я забыл сказать вам, что я использую PECrop для обрезки своих изображений, но я думаю, что это не примет участия в этой проблеме... - person Vergmort; 16.01.2014
comment
будет лучше, если вы покажете трассировку стека... А также приложение с инструментом утечки и распределения, это поможет вам сузить круг проблем. - person Adnan Aftab; 16.01.2014
comment
Запустите инструмент распределения и запустите приложение, вы найдете место, где память не выделяется, и приложение вылетает... - person Adnan Aftab; 16.01.2014
comment
Я сделаю это прямо сейчас и сообщу вам о результатах. Отличное предложение. - person Vergmort; 16.01.2014
comment
Все распределения кучи действительно потребляют только при съемке фотографии. Это невероятно. Сейчас я сделаю прибор для утечки. - person Vergmort; 16.01.2014
comment
эти распределения в библиотеке GPUIimage? - person Adnan Aftab; 16.01.2014
comment
Внутри All Heap Allocations большинство из них принадлежат Foundation, Core Graphics и Core Media. - person Vergmort; 16.01.2014
comment
:) Тогда возможно, что библиотека CPUImage делает некоторый рисунок с использованием CGContext и не освобождает память эффективно... - person Adnan Aftab; 16.01.2014
comment
Это не настоящая утечка памяти, но это случай неограниченного роста памяти, когда у объектов нет времени на освобождение, и приложение закрывается из-за проблемы с памятью. сразу после рисования... - person Adnan Aftab; 16.01.2014
comment
Но я нигде не использую CGContext! это становится трудно найти :( - person Vergmort; 16.01.2014
comment
Может быть, это использует библиотека GPUImage... не уверен, но в Интернете много тем о проблемах с утечкой GPUImage. - person Adnan Aftab; 16.01.2014
comment
Да, они... ну, в любом случае спасибо за помощь. Действительно приятно, рад, что в стеке есть такие люди, как ты, чувак! - person Vergmort; 16.01.2014
comment
@C_X Что такое неограниченный рост памяти? Есть ли способ избежать этого в нашем коде в общем смысле? Заранее спасибо. - person Unheilig; 16.01.2014
comment
Неограниченный рост памяти происходит там, где память продолжает выделяться и у нее никогда не будет возможности освободиться...! Иногда мы кэшируем некоторые объекты, помещаем их в какой-то словарь, но никогда не удаляем их, что может привести к неограниченному росту памяти. Мы не называем их настоящими утечками памяти, потому что, когда эта коллекция или блок закончатся и ссылки не будет, они будут освобождены. Но если их больше, и у нас никогда не будет возможности дераспределить ресурсы, iOS watchdog убьет наше приложение. - person Adnan Aftab; 16.01.2014
comment
Вы можете отслеживать их по инструменту распределения. Если выделенная память встает и встает, вы ... просто проверьте системную трассировку, элементы черного цвета принадлежат вашему коду, а серые - это в основном системные библиотеки. UIKIT и CoreGraphics выделяют много памяти, если не используются очень хорошо - person Adnan Aftab; 16.01.2014
comment
@C_X Спасибо за ответ. Я все еще пытаюсь разобраться в кэше деталей, некоторые объекты мы помещаем в какой-то словарь, но никогда не удаляем их... потому что, как только мы dealloc NSDictionary все ссылки, которые он сохраняет, будут автоматически освобождены. (было бы неплохо, если бы вы могли привести пример, но я боюсь, что прошу здесь слишком многого), но +1. - person Unheilig; 17.01.2014
comment
Да, ты прав. Я говорю кое-что еще, например, если мы загружаем некоторые изображения и помещаем их в какую-то коллекцию, это может быть словарь или массив, что угодно. и мы не используем их все, а используем некоторые из них, теперь они будут потреблять память, поэтому я хотел удалить вещи, которые больше не будут использоваться нами постоянно. Это может быть не в вашем случае, но это один из примеров того, как происходит неограниченный рост памяти. Или некоторое время мы выделяем временные объекты в цикле и не освобождаем их, эти объекты будут освобождены, когда пул автоматического освобождения будет исчерпан, но может быть, если слишком много, - person Adnan Aftab; 17.01.2014
comment
если слишком много временных объектов, у нас не будет возможности воспользоваться утечкой пула, iOS убьет нас. - person Adnan Aftab; 17.01.2014
comment
Если я найду ответ, я скажу вам, ребята. Надеюсь найти, не хочу использовать другой фреймворк для фотосъемки. - person Vergmort; 17.01.2014
comment
@C_X - Что касается этой ветки Google Groups, обратите внимание, что это среди людей, пытающихся использовать это с RubyMotion. У RubyMotion были проблемы с утечками памяти внутри себя: joshsymonds.com/blog/2013/06/26/ и обратите внимание, что предложенное там решение (добавление [super dealloc]), по-видимому, подразумевает, что они отключили ARC для этого проекта, когда GPUImage требует ARC для правильной работы. . Я не говорю, что GPUImage где-то не хватает памяти, но этот поток Google Groups, вероятно, не является хорошим ресурсом. - person Brad Larson; 17.01.2014
comment
Кроме того, это не связано с циклом сохранения из этого блока. Блок выполняется в соответствии с приведенным выше кодом и не сохраняется после этой точки. После этого блок и все, на что он ссылается (включая себя), должным образом освобождаются. Использование слабой ссылки здесь вам совсем не поможет. - person Brad Larson; 17.01.2014
comment
Да, мы выяснили, что это не из-за этого, и я предлагаю использовать __weak, потому что это лучшая практика, когда вы имеете дело с блоками. Вы можете предложить что-то лучше здесь ..! Я думал, что это может быть связано с тем, что объекты CoreGraphics не получают времени для выпуска, например, при рисовании с помощью CGContext, и не могут освободить память из-за сбоя при запуске приложения. Одна вещь, которую я понимаю из всего этого обсуждения, заключается в том, что это не сохранение или настоящая утечка памяти, это неограниченный рост памяти, и также возможно, что это происходит из-за GPUImage, потому что, увидев этот код, я могу сказать, что проблема не здесь. - person Adnan Aftab; 17.01.2014
comment
@BradLarson Я думаю, что вы являетесь автором этой библиотеки. Вы можете высказать экспертное мнение. Будет очень полезно, если вы укажете в каком-то направлении. - person Adnan Aftab; 17.01.2014
comment
@BradLarson Привет, Брэд, это приятно. Можете ли вы дать мне несколько советов о том, что происходит? - person Vergmort; 17.01.2014
comment
@C_X Эй, чувак, как дела? есть вопрос к вам. Есть ли способ стереть фотографию UIImageView пальцем на iOS? Есть ли какая-нибудь библиотека для этого? - person Vergmort; 22.01.2014
comment
Нет ничего, что iOS предоставляет вам ... но вы можете сделать это, создав эффект ластика, используя смешивание вещей и некоторые графические работы. - person Adnan Aftab; 22.01.2014
comment
Вот несколько ссылок, которые могут вам помочь, довольно круто и легко. stackoverflow.com/questions/11502320/ stackoverflow.com/questions/8441916/ - person Adnan Aftab; 22.01.2014