在后台线程中运行方法后,应用程序崩溃
我记录了我们可以拖动图像的主屏幕。在后台线程中运行方法后,应用程序崩溃
我有一个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];
}
可能的原因:
[self performSelectorInBackground:@selector(setNeedsDisplay) withObject:nil];
你从后台线程更新UI。 千万不要这样做,如果你需要用你的UI做些什么,在主线程中做。
而且我发现了你的代码的问题:
要调用从drawRect:
的setNeedsDisplay
它会再次调用drawRect:
。
(如果你需要更新您的视图中调用[self setNeedsDisplay];
,从不直接调用drawRect:
。)
相当恼人的是,所有setNeedsDisplay应该做的就是设置一个标志,以便将来重新绘制UI - 我希望能够从任何线程工作,并且重绘本身自动地在主线程上发生! +1得到的答案比我更快:)虽然:) – deanWombourne 2013-02-08 12:00:43
@deanWombourne:感谢您的信息和评论:) – 2013-02-08 12:19:30
是的你是对的,如果我使用主线程它的工作原理,但同样缓慢的拖动问题出现。 – 2013-02-08 12:57:47
我猜setNeedsDisplay:
必须在主线程中调用即可。大多数UI方法不适用于后台线程。
如果你把你的渲染方法放到你的问题中,我们可以看到它们是否可以改进?
只尝试设置setNeedsDisplayInRect:
如果你只想重画一部分显示?
是的你是对的,如果我使用它的主线程工作,但同样的缓慢拖动问题出现。而且,我实际上想要捕获我的应用程序的整个屏幕,因此不需要使用setNeedsDisplayInRect。 – 2013-02-08 12:54:19
为什么你想制作每一个单一的框架副本?这就是放慢速度的一切 - 我会试着找出一种方法让你的应用程序在不需要的情况下工作! – deanWombourne 2013-02-08 13:09:59
是这会减慢拖动对象的速度。是否有其他选项可以一次又一次地调用drawRect:方法来记录视频? – 2013-02-08 13:28:00
你不应该调用任何方法在后台线程中更新UI。始终从主线程更新UI。如果在调用setNeedsDisplay方法时调用drawrect,则不需要该行。
+1注意到'setNeedsDisplay:'正在从'drawRect:'内被调用 - 这不是一个好主意! – deanWombourne 2013-02-08 12:39:17
谢谢。那么应该在哪里调用setNeedsDisplay:方法? – 2013-02-08 13:00:23
我会在你的视图控制器中启动一个NSTimer,并从那里调用它。 – deanWombourne 2013-02-08 13:08:49
wt is errror displaed ?? ?? – iPatel 2013-02-08 11:55:15
你可以拖动对象成功? – iPatel 2013-02-08 11:57:59
@iPatel存在错误的访问错误。是的,我可以成功拖动对象。 – 2013-02-08 12:30:23