2015-07-10 74 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]; 
    } 
}