2015-07-10 71 views
0

我正在一個項目中,我必須嘗試在給定的時間執行給定的方法(見自動模式),如果自動模式不成功後,我切換到手動模式。只是爲了提醒你,我對Objective-C和iOS開發很陌生,所以錯誤可能很明顯。Objective-C內存問題與performSelector和無限循環

到目前爲止,這裏是我做了什麼:

-(void)viewDidLoad { 
    [self performSelector:@selector(autoMode) withObject:nil afterDelay:1.0]; 
    [self performSelectorInBackground:@selector(switchManualMode) withObject:nil]; 
} 


-(void)autoMode { 
    @autoreleasepool { 
     while (isAutoMode == true) { 
      if ([session isRunning]) 
       [self captureImage]; 
       // NSLog(@"test"); 
     } 
    } 
} 

-(void)switchManualMode { 
    [NSThread sleepForTimeInterval:2.0f]; 
    isAutoMode = false; 
    self.button.enabled = true; 

    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Changement de mode" 
                message:@"Du a un délai trop long, la capture automatique va être desactivée. La capture se fait maintenant de manière manuelle Touchez l'écran pour prendre une photo." 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil]; 

    [alert show]; 
} 

我有幾個問題在這裏:
- 第一個是內存使用的峯值和應用程序崩潰。
- 第二個是switchManualMode永遠不會被調用。

我試着只在日誌中打印「測試」(而不是實際調用函數「captureImage」),當我這樣做時,一切都很好。

我無法發佈captureImage的代碼,但該方法試圖從AVCaptureSession獲取圖像,然後對其進行索姆運算處理。
無論如何,我不明白爲什麼switchManualMode被調用的情況下,而不是在其他。

+0

幾點注意事項:爲什麼'@ autoreleasepool'?您必須指定'[alert show]'應該在主線程中執行 - 目前您正在使用後臺線程。一遍又一遍地捕捉圖像只會導致極高的CPU和內存使用量。 – luk2302

+0

我添加了@autoreleasepool,因爲這是我在尋找解決方案釋放無限循環時發現的。當我用NSLog替換captureImage的時候,[alert show]完美的工作。 – Chris

+0

它不能正常工作,它不確定在什麼時間點實際顯示警報視圖。如果它現在適合你:很好。它不會繼續。 – luk2302

回答

0

原因之一是你把@autoreleasepool放在錯誤的地方。它應該是裏面的循環。你正在的同一個自動釋放池中運行一個無限循環;這是要求解決內存不足的問題。以儘可能高的速度捕捉圖像並不完全有幫助。

另一個問題是performSelector將在主線程上運行,所以第二個performSelector將不會被調用,因爲第一次調用永遠不會返回。

你應該真的,擺脫performSelector並切換到GCD。我不想在今天編寫的任何代碼中看到performSelector和sleep調用。

+0

我在循環內移動了@autoreleasepool,並且內存一直在繼續。難道由於某種原因,captureImage方法中的某些元素會留在內存中嗎? 我會研究GCD,謝謝。 我知道我的第一個performSelector在主線程中運行,第二個在後臺運行,但是我怎麼能在用NSLog替換captureImage調用時調用switchManualMode? 是否應該每次或永遠不要調用它(因爲即使使用NSLog我也處於無限循環中)? – Chris

0

我傾向於使用遞歸這種類型的東西:

-(void)buttonTappedMethod 
{ 
    [self recusionMethod]; 
} 

-(void)recursionMethod 
{ 
    if(self.isAutoMode) 
    { 
     // ------------------------------------------------ 
     // Do something 
     // 
     // change self.isAutoMode = YES 
     // on condition satisfied in this logic block 
     // ------------------------------------------------ 

     // ------------------------------------------------ 
     // call this method again 
     // ------------------------------------------------ 
     [self recursionMethod]; 
    } 
}