2014-06-25 50 views
1

我正在使用AVFoundation將自定義相機集成到我的應用程序中......問題是,由於內存壓力,我正在發生罕見的但仍然發生的崩潰,我不確定爲什麼當我使用ARC和Xcode中的內存在崩潰時間周圍只有20mb左右?這是怎麼回事?AVFoundation自定義相機導致崩潰/內存壓力?

這裏是我的代碼

- (void)setupCamera 
    { 
     self.session = [[AVCaptureSession alloc] init]; 
     [self.session setSessionPreset:AVCaptureSessionPresetPhoto]; 

     AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; 
     if ([self.session canAddInput:input]) { 
      [self.session addInput:input]; 
     } 

     AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init]; 
     if ([self.session canAddOutput:output]) { 
      output.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 
      [self.session addOutput:output]; 
      [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 
     } 

     self.preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; 
     [self.preview setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 
     [self.preview setFrame:self.cameraView.frame]; 

     CALayer *cameraLayer = self.cameraView.layer; 
     [cameraLayer setMasksToBounds:YES]; 
     [cameraLayer addSublayer:self.preview]; 

     for (AVCaptureConnection *connection in output.connections) { 
      if (connection.supportsVideoOrientation) { 
       [connection setVideoOrientation:AVCaptureVideoOrientationPortrait]; 
      } 
     } 

     NSURL *shutterUrl = [[NSURL alloc] initWithString:[[NSBundle mainBundle] pathForResource: @"shutter" ofType: @"wav"]]; 
     self.shutterPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:shutterUrl error:nil]; 
     [self.shutterPlayer prepareToPlay]; 
    } 

    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
    { 
     if (self.doCapture) { 
      self.doCapture = NO; 

      [self.shutterPlayer setCurrentTime:0]; 
      [self.shutterPlayer play]; 

      CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
      CVPixelBufferLockBaseAddress(imageBuffer, 0); 
      void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

      size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
      size_t width = CVPixelBufferGetWidth(imageBuffer); 
      size_t height = CVPixelBufferGetHeight(imageBuffer); 

      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
      CGContextRef rawContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
      CGImageRef quartzImage = CGBitmapContextCreateImage(rawContext); 
      CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 
      CGContextRelease(rawContext); 
      CGColorSpaceRelease(colorSpace); 

      UIImage *rawImage = [UIImage imageWithCGImage:quartzImage]; 
      CGImageRelease(quartzImage); 

      float rawWidth = rawImage.size.width; 
      float rawHeight = rawImage.size.height; 
      CGRect cropRect = (rawHeight > rawWidth) ? CGRectMake(0, (rawHeight - rawWidth)/2, rawWidth, rawWidth) : CGRectMake((rawWidth - rawHeight)/2, 0, rawHeight, rawHeight); 
      CGImageRef croppedImageRef = CGImageCreateWithImageInRect([rawImage CGImage], cropRect); 

      UIImage *croppedImage = [UIImage imageWithCGImage:croppedImageRef]; 
      CGImageRelease(croppedImageRef); 

      [self saveImage:croppedImage]; 
     } 
    } 

    - (void)saveImage:(UIImage *)image 
    { 
     [self.capturedImages addObject:image]; 

     NSArray *scrollItemXIB = [[NSBundle mainBundle] loadNibNamed:@"SellPreviewImagesScrollItemView" owner:self options:nil]; 
     UIView *scrollItemView = [scrollItemXIB lastObject]; 

     UIImageView *previewImage = (UIImageView *)[scrollItemView viewWithTag:PREVIEW_IMAGES_SCROLL_ITEM_TAG_IMAGE]; 
     previewImage.image = image; 

     UIButton *deleteButton = (UIButton *)[scrollItemView viewWithTag:PREVIEW_IMAGES_SCROLL_ITEM_TAG_BADGE_BUTTON]; 
     [deleteButton addTarget:self action:@selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside]; 

     UIButton *previewButton = (UIButton *)[scrollItemView viewWithTag:PREVIEW_IMAGES_SCROLL_ITEM_TAG_BUTTON]; 
     [previewButton addTarget:self action:@selector(previewImage:) forControlEvents:UIControlEventTouchUpInside]; 

     [self addItemToScroll:scrollItemView]; 
     [self checkCapturedImagesLimit]; 

     if ([self.capturedImages count] == 1) { 
      [self makeCoverPhoto:[self.capturedImages objectAtIndex:0]]; 
      [self cells:self.previewImagesToggle setHidden:NO]; 
      [self reloadDataAnimated:YES]; 
     } 
    } 
+0

你是否運行過儀器 - 特別是Allocations模板? – ChrisH

回答

0

如果您設置self.doCapture =真的嗎?好像你爲臨時對象分配了大量內存。嘗試使用@autoreleasepool指令:

@autoreleasepool { 
    self.doCapture = NO; 

    [self.shutterPlayer setCurrentTime:0]; 
    [self.shutterPlayer play]; 

     ... 

    if ([self.capturedImages count] == 1) { 
     [self makeCoverPhoto:[self.capturedImages objectAtIndex:0]]; 
     [self cells:self.previewImagesToggle setHidden:NO]; 
     [self reloadDataAnimated:YES]; 
    } 

}

+0

self.doCapture在按下界面中的按鈕時設置 –

+0

您會提供崩潰信息嗎? –

+0

這只是一個「由於內存壓力而終止」的崩潰。如果您願意,我可以使用配置文件截圖分配診斷。 –

0

我想我可能有同樣的問題(「由於終止內存壓力」),我只是改變了AVCaptureSession的設置從viewDidAppear到ViewDidLoad。它在iPad上增長到100mb左右,現在它將上升到14mb,並在頂部放置一個大圖片。

相關問題