在CTCallCenter callEventHandler中取消隐藏视图非常慢

dji*_*i33 7 iphone objective-c grand-central-dispatch ios core-telephony

在原始问题没有回答之后重新发布更简洁和专注的问题.在另一天的研究之后,还要对问题进行更深入的了解:

在我的app delegate(didFinishLaunching)中,我设置了一个callEventHandleron CTCallCenter.我的想法是,当callState发生变化时,我会发布一个包含userInfo dict的通知call.callState.在我看来,我观察到这个通知,当 userInfodict包含值时CTCallDisconnected,我想取消隐藏视图.

我遇到的问题是,无需担心的方面,几乎是一致的,约7秒钟.其他一切工作正常,我知道这是因为我NSLog在取消隐藏之前和之后,这些日志立即出现,但是看不见的视图仍然滞后7秒.

这是我的代码:

appDidFinishLaunching:

self.callCenter = [[CTCallCenter alloc] init];
    self.callCenter.callEventHandler = ^(CTCall* call) {
        // anounce that we've had a state change in our call center
        NSDictionary *dict = [NSDictionary dictionaryWithObject:call.callState forKey:@"callState"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"CTCallStateDidChange" object:self userInfo:dict];
    };
Run Code Online (Sandbox Code Playgroud)

然后,当用户点击拨打电话号码的按钮时,我会收听此通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ctCallStateDidChange:) name:@"CTCallStateDidChange" object:nil];
Run Code Online (Sandbox Code Playgroud)

然后,在ctCallStateDidChange中:

- (void)ctCallStateDidChange:(NSNotification *)notification
{
   NSLog(@"121");
   NSString *callInfo = [[notification userInfo] objectForKey:@"callState"];
   if ([callInfo isEqualToString:CTCallStateDisconnected]) {
      NSLog(@"before show");
      [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
      NSLog(@"after show");
   }
}
Run Code Online (Sandbox Code Playgroud)

我已将问题跟踪到上面代码示例中的if条件:

 if ([[userInfo valueForKey:@"userInfo"] valueForKey:@"callState"] == CTCallStateDisconnected) {
Run Code Online (Sandbox Code Playgroud)

如果我只是用以下内容替换:

if (1 == 1) {
Run Code Online (Sandbox Code Playgroud)

然后立即出现视图!

问题是,这些NSLog陈述是立即记录的,但是视图是滞后于它的隐藏.那个条件怎么可能只导致它的一部分块立即执行,其余的等待~7秒?

谢谢!

Tho*_*ler 10

尝试将代码更改为:

- (void)ctCallStateDidChange:(NSNotification *)notification
{
   NSLog(@"121");
   NSString *callInfo = [[notification userInfo] objectForKey:@"callState"];
   if ([callInfo isEqualToString:CTCallStateDisconnected]) {
      NSLog(@"before show");
      [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
      NSLog(@"after show");
   }
}
Run Code Online (Sandbox Code Playgroud)

注意:

  • 参数是a NSNotification,而不是NSDictionary
  • 我不会比较字符串 ==
  • 无需转换视图来更改hidden属性
  • NO而不是false

更新:有个主意:请问你能在NSLogs 之间尝试以下方法吗?

dispatch_async(dispatch_get_main_queue(), ^{
   [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
});
Run Code Online (Sandbox Code Playgroud)

阅读CTCallCenter文档,似乎callEventHandler是在"默认优先级全局调度队列"上调度,这不是发生所有UI内容的主队列.

  • 我认为问题是`callEventHandler`不在主队列中运行.也许,在那里,在主队列上做所有通知中心的东西(使用`dispatch_async`,就像在我的更新中一样).另外,我建议在您的问题中添加[grand-central-dispatch]标签. (6认同)