2013-01-15 78 views
2

我正在開發一個應用程序,使用NSInvocation作爲下面的代碼處理NSTimer。我得到Sigbart以下代碼錯誤*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSInvocation invocationWithMethodSignature:]: method signature argument cannot be nil' *** First throw call stackiOS:invocationWithMethodSignature方法簽名參數問題

我試圖找出這個崩潰,但無法得到它。有人可以幫我解決這個問題嗎?

代碼:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveImageToPhotoAlbum) name:kImageCapturedSuccessfully object:nil]; 

    NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(capturePicture:)]]; 
    [myInvocation setSelector:@selector(capturePicture:)]; 
    [myInvocation setTarget:self]; 
    [myInvocation retainArguments]; 

    [NSTimer scheduledTimerWithTimeInterval:5.0 invocation:myInvocation repeats:NO]; 




    -(void) capturePicture :(id) sender 
{ 
    NSLog(@"capTureAutoPicture:Scanning image at interval"); 

    // Get all cameras in the application and find the frontal camera. 
    AVCaptureDevice *backCamera; 
    NSArray *allCameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 

    // Find the back camera. 
    for (int i = 0; i < allCameras.count; i++) { 
     AVCaptureDevice *camera = [allCameras objectAtIndex:i]; 

     if (camera.position == AVCaptureDevicePositionBack) { 
      backCamera = camera; 
     } 
    } 

    // If we did not find the camera then do not take picture. 
    if (backCamera != nil) { 
     // Start the process of getting a picture. 
     AVCaptureSession *session = [[AVCaptureSession alloc] init]; 

     // Setup instance of input with back camera and add to session. 
     NSError *error; 
     AVCaptureDeviceInput *input = 
     [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error]; 

     if (!error && [session canAddInput:input]) { 
      // Add frontal camera to this session. 
      [session addInput:input]; 

      // We need to capture still image. 
      AVCaptureStillImageOutput *output = [[AVCaptureStillImageOutput alloc] init]; 

      // Captured image. settings. 
      [output setOutputSettings: 
      [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]]; 

      if ([session canAddOutput:output]) 
      { 

       [session addOutput:output]; 

       AVCaptureConnection *videoConnection = nil; 
       for (AVCaptureConnection *connection in output.connections) { 
        for (AVCaptureInputPort *port in [connection inputPorts]) { 
         if ([[port mediaType] isEqual:AVMediaTypeVideo]) 
         { 
          videoConnection = connection; 
          break; 
         } 
        } 
        if (videoConnection) 
        { 
         break; 
        } 
       } 

       // Finally take the picture 
       if (videoConnection) 
       { 
        [session startRunning]; 

        [output captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) 
        { 
         if (imageDataSampleBuffer != NULL) 
         { 
          NSData *imageData = [AVCaptureStillImageOutput 
                jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 
          UIImage *photo = [[UIImage alloc] initWithData:imageData]; 

          //UIImageWriteToSavedPhotosAlbum(photo, nil, nil, nil); 
          [photo release]; 

          [[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil]; 

          [session stopRunning]; 

         } 

        }]; 

       } 
      } 
      [output release]; 
     } 
    } 
} 
- (void)saveImageToPhotoAlbum 
{ 
    UIImageWriteToSavedPhotosAlbum([self stillImage], self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 

    [self dismissModalViewControllerAnimated:YES]; 
} 

更新的代碼:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveImageToPhotoAlbum) name:kImageCapturedSuccessfully object:nil]; 

    /*NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(capTureAutoPicture)]]; 
    [myInvocation setSelector:@selector(capTureAutoPicture)]; 
    [myInvocation setTarget:self]; 
    [NSTimer scheduledTimerWithTimeInterval:5.0 invocation:myInvocation repeats:NO];*/ 

    [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(capTureAutoPicture:) userInfo:nil repeats:NO]; 
+0

你可以發佈'[self methodSignatureForSelector:@selector(capturePicture :)]'的代碼嗎?看起來這種方法並沒有返回你認爲的那樣。 – MishieMoo

+0

我更新了我的代碼,我現在沒有在scheduledTimerWithTimeInterval中使用NSInvocation,但由於此行同樣發生崩潰[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil]; ..有幫助嗎? – Getsy

回答

2

引發的異常是相當清楚的參數不能是零。

下面是一個NSInvocation的的工作示例:

NSMethodSignature *methodSignature = [[_filter class] instanceMethodSignatureForSelector:@selector()]; 
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; 
[invocation setTarget:_filter]; 
[invocation setSelector:selector]; 
[invocation setArgument:&value atIndex:2]; 
[invocation invoke]; 

我也建議你看看answer to this question解釋真的很好NSInvocation的工作原理

+0

我試圖刪除scheduledTimerWithTimeInterval使用的整個NSInvocation代碼,並正常使用scheduledTimerWithTimeInterval作爲更早沒有NSInvocation,但仍然相同的崩潰即將到來,我不明白爲什麼。我還發現,如果我評論[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil];在塊代碼中,沒有崩潰,但它用於回到前一個屏幕。 – Getsy

+0

我更新了我的代碼,我現在沒有在scheduledTimerWithTimeInterval中使用NSInvocation,但由於此行發生同樣的崩潰[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil]; ..有幫助嗎? – Getsy

0

我固定它。問題是,我沒有添加「didFinishSavingWithError」,而是調用它。在添加這個定義後,它就起作用了。