在我的应用程序中,我有一个对象CameraHandler
,该对象使用GPUImage来检测相机的某些运动。它在我的GameViewController
中初始化。
它(CameraHandler
)能够成功检测运动并触发相关方法,但是在屏幕上显示任何更改之前,它会锁定GameViewController
的视图相当长的时间(约5至10秒)。 CameraHandler
检测到更改后,将触发一种方法,该方法将更改视图控制器上顶视图的背景并显示UIAlertView
(用于测试)。就像我说的那样,这种情况只会在调用后的5-10秒后发生。我知道程序本身没有冻结,因为我从方法中获取了相关的日志输出。我尝试了不同的方法来尝试解决此问题,但是我已经空手了几周了。
在GameViewController(我在其中调用并启动CameraHandler)中:
-(void)startRound{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
[_shotDetector captureStillImage];
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"finish capture still image thread");
});
});
}
/* this method gets called from CameraHandler once it detects movement */
-(void)shotLifted:(NSNumber*)afterTime{
NSLog(@"shot lifted fired");
UIAlertView *lost = [[UIAlertView alloc]initWithTitle:@"Good Job!" message:@"Shot lifted in time" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[lost show];
[_questionView setBackgroundColor:[UIColor whiteColor]];
NSLog(@"shot lifted done");
}
CameraHandler.h
@interface CameraHandler : NSObject <GPUImageVideoCameraDelegate>
@property (strong) GPUImageOutput<GPUImageInput> *filter,*emptyFilter;
@property (strong) GPUImageVideoCamera *videoCamera;
@property (strong) GPUImagePicture *sourcePicture;
@property (strong) GPUImageOutput *pictureOutput;
@property (strong) GPUImageStillCamera *stillCamera;
@property (strong) __block UILabel *shotRemovedLabel;
@property (strong) __block NSDate *startTime;
@property (strong) NSMutableArray *averageLum;
@property (strong) id delegate;
@property (strong) GPUImageLuminosity *lumin;
CameraHandler.m -相关方法
-(void)startBlackoutShotMotionAnalysis{
NSLog(@"starting shot motion analysis");
[_videoCamera addTarget:self.filter];
[_sourcePicture processImage];
[_sourcePicture addTarget:self.filter];
[_videoCamera startCameraCapture];
_lumin = [[GPUImageLuminosity alloc] init];
[self.filter addTarget:_lumin];
__block int i =0;
__unsafe_unretained GameViewController* weakDelegate = self.delegate;
//begin luminosity detecting of live-video from uiimage
[(GPUImageLuminosity *)_lumin setLuminosityProcessingFinishedBlock:^(CGFloat luminosity, CMTime frameTime) {
if(i<60){
if(i>10){
_startTime = [NSDate date];
[_averageLum addObject:[NSNumber numberWithFloat:luminosity]];
}
i++;
}
else{
CGFloat average = [[_averageLum valueForKeyPath:@"@avg.floatValue"]floatValue];
CGFloat difference = fabsf(luminosity-average);
if(difference > 0.05){
NSTimeInterval liftedAfter = [_startTime timeIntervalSinceDate:[NSDate date]];
[weakDelegate performSelector:@selector(shotLifted:) withObject:[NSNumber numberWithFloat:liftedAfter]];
[_videoCamera stopCameraCapture];
NSLog(@"should turn white now");
return ;
}
}
}];
NSLog(@"finished returning executing starBlackoutMotionAnalysis Method");
}
NSLOG输出:
2014-04-08 20:22:45.450 Groupy[2887:5c0f] starting shot motion analysis
2014-04-08 20:22:46.152 Groupy[2887:5c0f] finished returning executing starBlackoutMotionAnalysis Method
2014-04-08 20:22:48.160 Groupy[2887:1303] shot lifted fired
2014-04-08 20:22:48.221 Groupy[2887:1303] shot lifted done
2014-04-08 20:22:48.290 Groupy[2887:1303] should turn white now
在正确方向上的任何帮助都是巨大的。我一直在努力解决这个问题。谢谢!
最佳答案
当我在UI中看到异常延迟的更新时,通常要寻找的第一件事是是否在主队列上执行我的UI更新代码。除了少数例外,您应该始终将任何与UI相关的代码分派到主队列中,否则会出现类似这样的怪异行为。
据我所知,您可以直接在shotLifted:
内部执行luminosityProcessingFinishedBlock
选择器。我们可以安全地假设GPUImage将在主线程中调用该块。这意味着您初始化和显示警报视图的代码也在主线程之外发生。
要更改此设置,您应该尝试将对shotLifted:
的调用包装在一个块中,并将其分派到主队列:
dispatch_async(dispatch_get_main_queue(), ^{
[weakDelegate performSelector:@selector(shotLifted:) withObject:obj];
}
或者,您可以执行以下操作:
[weakDelegate performSelectorOnMainThread:@selector(shotLifted:) withObject:obj waitUntilDone:NO];
关于ios - GPUImage锁定 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22950723/