2013-09-27 3 views
4

Теперь я пишу программу для захвата экрана и преобразования в видео. Я могу успешно сохранить видео, если оно меньше 10 секунд. Но, если более того, я получил предупреждение о сбоях в памяти и крах приложения. Я написал этот код следующим образом. Где мне не хватает данных? Я хотел бы знать, как это сделать.Предупреждение о сохранении памяти при захвате экрана и сохранении на видео ios

-(void)captureAndSaveImage 
{ 

if(!stopCapturing){ 

if (assetWriterInput.readyForMoreMediaData) 
{ 
    keepTrackOfBackGroundMood++; 
    NSLog(@"keepTrackOfBackGroundMood is %d",keepTrackOfBackGroundMood); 

    CVReturn cvErr = kCVReturnSuccess; 

    CGSize imageSize = screenCaptureAndDraw.bounds.size; 


    CGFloat imageScale = 0; //if zero, it reduce processing time 

    if (NULL != UIGraphicsBeginImageContextWithOptions) 
    { 
     UIGraphicsBeginImageContextWithOptions(imageSize, NO, imageScale); 
    } 
    else 
    { 
     UIGraphicsBeginImageContext(imageSize); 
    } 

    [self.hiddenView.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    [self.screenCaptureAndDraw.layer renderInContext:UIGraphicsGetCurrentContext()]; 


    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 



    image = (CGImageRef) [img CGImage]; 

    CVPixelBufferRef pixelBuffer = NULL; 
    CFDataRef imageData= CGDataProviderCopyData(CGImageGetDataProvider(image)); 
    cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, 
             FRAME_WIDTH2, 
             FRAME_HEIGHT2, 
             kCVPixelFormatType_32BGRA, 
             (void*)CFDataGetBytePtr(imageData), 
             CGImageGetBytesPerRow(image), 
             NULL, 
             NULL, 
             NULL, 
             &pixelBuffer); 


    //CFRelease(imageData); 
    //CGImageRelease(image); //I can't write this code because I am not creating it and when I check online, it say it is not my responsibility to release. If I write, the application crash immediately 


    // calculate the time 
    CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent(); 
    CFTimeInterval elapsedTime = thisFrameWallClockTime - firstFrameWallClockTime; 


    // write the sample 

    BOOL appended = [assetWriterPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentationTime]; 

    if (appended) { 
     NSLog (@"appended sample at time %lf and keepTrackofappended is %d", CMTimeGetSeconds(presentationTime),keepTrackofappended); 
     keepTrackofappended++; 
    } else { 
     NSLog (@"failed to append"); 
     [self stopRecording]; 
     //self.startStopButton.selected = NO; 
     screenRecord=false; 
    } 



} 

}//stop capturing 
// }); 


} 
+0

У вас должна быть какая-то утечка (по крайней мере, я раскомментирую 'CFRelease (imageData)' и не забываю 'CVPixelBufferRelease'). Я только что протестировал захват кадров в 1200, и это было хорошо на моем iPhone 5. И когда я тестировал в Инструментах, распределения были плоскими, поэтому, если у вас нет утечки, вы должны быть в порядке. – Rob

ответ

2

Я согласен с тем, что вы не хотите делать CGImageRelease(image). Этот объект был создан путем вызова метода CGImage объекта UIImage. Таким образом, собственность не была передана, и ARC по-прежнему выполняет управление памятью для вашего объекта img и не требует освобождения объекта image.

Но я думаю, вы do хотите восстановить CFRelease(imageData). Это объект, созданный CGDataProviderCopyData, так что вы его владельцем и должны очистить.

Я также считаю, что вам необходимо освободить pixelBuffer, который вы создали с помощью CVPixelBufferCreateWithBytes после вас. appendPixelBuffer. Для этого вы можете использовать функцию CVPixelBufferRelease.

Правило памяти Core Foundation заключается в том, что если функция имеет имя Copy или Create, вы являетесь владельцем этого объекта и несете ответственность за его освобождение. См. Create Rule в Руководстве по программированию управления памятью для ядра Core .

я бы подумал, что статический анализатор (сдвиг + команда + B или «Анализ» из меню Xcode «Продукт») бы определил этот вопрос, так как он получил гораздо лучше нахождение проблем с памятью Core Foundation (хотя и не идеально).

В качестве альтернативы, если вы запустите приложение с помощью инструмента «Утечки» в «Инструменты» (которое одновременно покажет вам инструмент «Распределения»), вы можете взглянуть на использование вашей памяти. В то время как для захвата видео требуется много Live Bytes, по моему опыту он остается довольно плотным. Если он растет, у вас где-то есть утечка.

+0

О, спасибо, Роб. Ты мне действительно поможешь. Я думаю, что теперь он решает проблему утечки памяти. Я снова проверю статический анализатор. –

+0

@Rob решено? –

+0

@ user1111 Да, 'CFRelease (imageData)' и 'CVPixelBufferRelease (pixelBuffer)' (но не 'CGImageRelease (image)') должны исправить утечки. – Rob

Смежные вопросы