Ios 带有performSelector和无限循环的Objective-C内存问题

Ios 带有performSelector和无限循环的Objective-C内存问题,ios,objective-c,memory,infinite-loop,performselector,Ios,Objective C,Memory,Infinite Loop,Performselector,我正在做一个项目,在这个项目中,我必须在给定的时间内尝试执行给定的方法(就像自动模式一样),如果自动模式不成功,我将切换到手动模式。我只是想提醒你,我对Objective-C和iOS开发还很陌生,所以错误可能很明显 到目前为止,我所做的是: -(void)viewDidLoad { [self performSelector:@selector(autoMode) withObject:nil afterDelay:1.0]; [self performSelectorI

我正在做一个项目,在这个项目中,我必须在给定的时间内尝试执行给定的方法(就像自动模式一样),如果自动模式不成功,我将切换到手动模式。我只是想提醒你,我对Objective-C和iOS开发还很陌生,所以错误可能很明显

到目前为止,我所做的是:

-(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

我试着在日志中打印“test”(而不是实际调用函数“captureImage”),当我这样做时,一切都很好

我无法发布captureImage的代码,但该方法尝试从AVCaptureSession获取图像,然后对其进行somme处理。

无论如何,我不明白为什么在一个案例中调用switchManualMode而在另一个案例中不调用switchManualMode。

一个原因是您将@autoreleasepool放在了错误的位置。它应该在循环中。您正在同一自动释放池中运行无限循环;这是要求内存不足的问题。以尽可能高的速度拍摄图像并没有什么帮助

另一个问题是performSelector将在主线程上运行,因此不会调用第二个performSelector,因为第一个调用永远不会返回


你应该真的,真的摆脱performSelector,转而使用GCD。我不想在今天编写的任何代码中看到performSelector和sleep调用

我倾向于对这类事情使用递归:

-(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];
    }
}

注意:为什么
@autoreleasepool
?您必须指定应在主线程上执行
[alert show]
——当前您正在后台线程上操作。一次又一次地捕获图像只会导致极高的cpu和内存使用率。我添加了@autoreleasepool,因为这是我在寻找无限循环释放内存的解决方案时发现的。当我在评论中将captureImage替换为NSLog时,[alert show]工作得很好。它不会工作得很好,无法确定在什么时间点实际显示警报视图。如果它现在对你有效:太好了。它将不会继续。好的,我将尝试找到一种方法“强制”它在主线程上执行。您是如何定义
isAutoMode
var的?我将@autoreleasepool移动到循环中,内存继续运行。captureImage方法中的某些元素会因为某种原因留在内存中吗?我会调查GCD的,谢谢。我知道我的第一个performSelector在主线程中运行,第二个在后台运行,但是当我用NSLog替换captureImage调用时,怎么会调用switchManualMode呢?它应该每次调用还是从不调用(因为即使使用NSLog,我也处于无限循环中)?