2014-01-22 144 views
1

在我的应用程序,我需要检测是否ImagePicker准备拍照。我发现这里的解决方案:How to know if iPhone camera is ready to take picture?iOS NSNotificationCenter奇怪的延迟

所以我得到这个代码viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(showButton:) 
name:AVCaptureSessionDidStartRunningNotification object:nil]; 

和选择是这样的:

- (void)showButton:(NSNotification *)notification{ 

    NSLog(@"---CAMERA READY"); 

    [button setHidden:NO]; 
    [button setAlpha:0.0]; 
    [button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5)]; 

    [UIView animateWithDuration:.2 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ 
     [button setAlpha:1.0]; 
     [button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0)]; 
    } completion:^(BOOL finished) { 

    }]; 

    NSLog(@"---CAMERA READY"); 

} 

这里是一些奇怪的事情发生,因为这两个NSLogs立即显示,但整个按钮动画甚至会在30秒后触发。

UIView是否单独更新?我如何同步日志和动画?

+2

您可以检查是否收到AVCaptureSessionDidStartRunningNotification在后台线程?修改UI只能从主线程完成 – rist

+0

我试过'dispatch_queue_t queue = dispatch_get_main_queue();'''dispatch_async',它现在可以工作,所以这是线程问题。 – cyborg86pl

回答

2

打算把这个回答框为未来的用户看到..

什么您遇到使它看起来像您的通知不被称为主线程,并更新在用户界面后台线程是未定义的行为。解决这个问题很简单,只需将方法的内容包装在dispatch_async()调用中,并将所有内容都发送回主队列。

- (void)showButton:(NSNotification *)notification { 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSLog(@"---CAMERA READY"); 

     [button setHidden:NO]; 
     [button setAlpha:0.0]; 
     [button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5)]; 

     [UIView animateWithDuration:.2 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ 
      [button setAlpha:1.0]; 
      [button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0)]; 
     } completion:nil]; 

     NSLog(@"---CAMERA READY"); 
    }); 
} 

作为一种替代方法,您可以使用不同的NSNotificationCenter实例方法。具体来说,-addObserverForName:object:queue:usingBlock:允许您指定应在哪个操作队列上执行回调块。在这种情况下,您想要通过[NSOperationQueue mainQueue];

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNotificationCenter/addObserverForName:object:queue:usingBlock

NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; 
self.localeChangeObserver = [center addObserverForName:NSCurrentLocaleDidChangeNotification object:nil 
    queue:mainQueue usingBlock:^(NSNotification *note) { 

     NSLog(@"The user's locale changed to: %@", [[NSLocale currentLocale] localeIdentifier]); 
    }];