在后台线程中运行方法后,应用程序崩溃

问题描述:

我记录了我们可以拖动图像的主屏幕。在后台线程中运行方法后,应用程序崩溃

我有一个setneedsdisplay方法,可以减慢拖动的对象。

但是,当我在后台线程调用相同的方法问题已解决,但应用程序崩溃。

此外,如果有任何其他选项来记录视频,而不是一次又一次调用drawRect:方法?

- (void) drawRect:(CGRect)rect { 
    NSDate* start = [NSDate date]; 
    CGContextRef context = [self createBitmapContextOfSize:self.frame.size]; 


    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.frame.size.height); 
    CGContextConcatCTM(context, flipVertical); 

    [self.layer renderInContext:context]; 

    CGImageRef cgImage = CGBitmapContextCreateImage(context); 
    UIImage* background = [UIImage imageWithCGImage: cgImage]; 
    CGImageRelease(cgImage); 

    self.currentScreen = background; 

    if (_recording) { 
     float millisElapsed = [[NSDate date] timeIntervalSinceDate:startedAt] * 1000.0; 
     [self writeVideoFrameAtTime:CMTimeMake((int)millisElapsed, 1000)]; 

    } 

    float processingSeconds = [[NSDate date] timeIntervalSinceDate:start]; 
    delayRemaining = (1.0/self.frameRate) - processingSeconds; 



    //CGContextRelease(context); 

    //redraw at the specified framerate 
    //[self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:delayRemaining > 0.0 ? delayRemaining : 0.01]; 

    [self performSelectorInBackground:@selector(setNeedsDisplay) withObject:nil]; 

} 
+1

wt is errror displaed ?? ?? – iPatel 2013-02-08 11:55:15

+0

你可以拖动对象成功? – iPatel 2013-02-08 11:57:59

+0

@iPatel存在错误的访问错误。是的,我可以成功拖动对象。 – 2013-02-08 12:30:23

可能的原因:

[self performSelectorInBackground:@selector(setNeedsDisplay) withObject:nil]; 

你从后台线程更新UI。 千万不要这样做,如果你需要用你的UI做些什么,在主线程中做。

而且我发现了你的代码的问题:

要调用从drawRect:setNeedsDisplay它会再次调用drawRect:

(如果你需要更新您的视图中调用[self setNeedsDisplay];,从不直接调用drawRect:。)

+0

相当恼人的是,所有setNeedsDisplay应该做的就是设置一个标志,以便将来重新绘制UI - 我希望能够从任何线程工作,并且重绘本身自动地在主线程上发生! +1得到的答案比我更快:)虽然:) – deanWombourne 2013-02-08 12:00:43

+0

@deanWombourne:感谢您的信息和评论:) – 2013-02-08 12:19:30

+0

是的你是对的,如果我使用主线程它的工作原理,但同样缓慢的拖动问题出现。 – 2013-02-08 12:57:47

我猜setNeedsDisplay:必须在主线程中调用即可。大多数UI方法不适用于后台线程。

如果你把你的渲染方法放到你的问题中,我们可以看到它们是否可以改进?

只尝试设置setNeedsDisplayInRect:如果你只想重画一部分显示?

+0

是的你是对的,如果我使用它的主线程工作,但同样的缓慢拖动问题出现。而且,我实际上想要捕获我的应用程序的整个屏幕,因此不需要使用setNeedsDisplayInRect。 – 2013-02-08 12:54:19

+0

为什么你想制作每一个单一的框架副本?这就是放慢速度的一切 - 我会试着找出一种方法让你的应用程序在不需要的情况下工作! – deanWombourne 2013-02-08 13:09:59

+0

是这会减慢拖动对象的速度。是否有其他选项可以一次又一次地调用drawRect:方法来记录视频? – 2013-02-08 13:28:00

你不应该调用任何方法在后台线程中更新UI。始终从主线程更新UI。如果在调用setNeedsDisplay方法时调用drawrect,则不需要该行。

+0

+1注意到'setNeedsDisplay:'正在从'drawRect:'内被调用 - 这不是一个好主意! – deanWombourne 2013-02-08 12:39:17

+0

谢谢。那么应该在哪里调用setNeedsDisplay:方法? – 2013-02-08 13:00:23

+0

我会在你的视图控制器中启动一个NSTimer,并从那里调用它。 – deanWombourne 2013-02-08 13:08:49