Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 在名为Venthandler的CTCallCenter中,取消隐藏视图的速度非常慢_Iphone_Objective C_Ios_Grand Central Dispatch_Core Telephony - Fatal编程技术网

Iphone 在名为Venthandler的CTCallCenter中,取消隐藏视图的速度非常慢

Iphone 在名为Venthandler的CTCallCenter中,取消隐藏视图的速度非常慢,iphone,objective-c,ios,grand-central-dispatch,core-telephony,Iphone,Objective C,Ios,Grand Central Dispatch,Core Telephony,在原始问题未得到回答后,重新发布更简洁、更集中的问题。在另一天的研究之后,也增加了对问题的更多洞察: 在我的应用程序代理(didfishLaunching)中,我在CTCallCenter上设置了一个名为venthandler。 其思想是,当调用状态发生变化时,我使用userInfo dict发布通知 包含call.callState。在我看来,我遵守此通知,并且 userInfodict包含值CTCallDisconnected,我想取消隐藏视图 我遇到的问题是,取消隐藏方面几乎持续地需要约7

在原始问题未得到回答后,重新发布更简洁、更集中的问题。在另一天的研究之后,也增加了对问题的更多洞察:

在我的应用程序代理(
didfishLaunching
)中,我在
CTCallCenter
上设置了一个名为
venthandler
。 其思想是,当调用状态发生变化时,我使用userInfo dict发布通知 包含
call.callState
。在我看来,我遵守此通知,并且
userInfo
dict包含值
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];
    };
然后,当用户点击拨打电话号码的按钮时,我会监听此通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ctCallStateDidChange:) name:@"CTCallStateDidChange" object:nil];
然后,在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");
   }
}
我已经在上面的代码示例中跟踪到了问题的if条件:

 if ([[userInfo valueForKey:@"userInfo"] valueForKey:@"callState"] == CTCallStateDisconnected) {
如果我简单地将其替换为:

if (1 == 1) {
然后视图立即出现

问题是,那些
NSLog
语句会立即记录,但视图是 在这方面落后是不隐藏的。这种情况怎么可能只造成部分阻塞 立即执行,其余等待约7秒


谢谢

看起来您的隐藏代码没有问题。如果我是你,我会在调用结束后注释掉所有代码,然后逐个取消注释以查看问题所在。

Hm。。。更改隐藏属性后,尝试调用
[yourViewController.view setNeedsDisplay]
。或者避免隐藏,请使用alpha或addSubview:并从SuperView方法中删除。

尝试将代码更改为:

- (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");
   }
}
注:

  • 该参数是
    NSNotification
    ,而不是
    NSDictionary
  • 我不会将字符串与
    =
  • 无需强制转换视图即可更改
    hidden
    属性
  • 使用
    NO
    而不是
    false
更新:有了一个想法:在
NSLog
s之间,您可以尝试以下方法吗

dispatch_async(dispatch_get_main_queue(), ^{
   [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
});
阅读
CTCallCenter
doc,似乎
callEventHandler
是在“默认优先级全局调度队列”上调度的,该队列不是所有UI工作发生的主队列。

当用户点击拨打电话号码的按钮时,你把这句话放在哪里听?在WillResignative功能上

这句话-->[[NSNotificationCenter defaultCenter]addObserver:自选择器:@selector(ctCallStateDidChange:)name:@“ctCallStateDidChange”对象:nil]

谢谢你抽出时间


威利。

隐藏/显示视图的过程非常快。问题在于视图及其superview的内容。你试过用仪器分析这个案子吗?张贴代码,您可以在其中配置隐藏的视图和隐藏后显示的视图。谢谢。刚刚更新了我原来的帖子。视图中的图像是4KB,所以我认为这不是问题。我只是试着忽略了图像,但仍然存在延迟。不太熟悉仪器。我只通过该工具查看了内存泄漏,所以我不太确定如何检查幕后的情况。使用时间配置文件,它将显示每个时刻的调用堆栈以及每个函数的工作时间。如果您检查CTCallCenter何时发出通知,肯定会有所帮助。可能是迟到了,不是通知,我知道这一点,因为我可以在事件处理程序回调中记录显示视图的代码之前和之后。NSLog立即出现在控制台中。由于第二次回调在“出现”代码之后,我知道它已经运行了。问题是它有几秒钟没有出现。谢谢,但这似乎不起作用。在我的回调处理程序中,我在显示视图后取消了所有注释,但仍有7秒的延迟。感谢您的所有建议@Zapko。我刚刚发现,如果删除测试appDelegate.userInitiatedCall.callState的条件,所有内容都会立即显示出来。不知道为什么在应用程序代理上检查ivar要花这么长时间。有什么想法吗?您应该记住,当您编写
appDelegate.userInitiatedCall.callState==something
时,它没有检查它正在调用的iVar 2个方法
[[appDelegate userInitiatedCall]callState]
。这种方法的执行时间取决于它们的复杂性。例如,如果您只是合成了它们,但没有将它们设置为非原子的,那么执行它们所需的时间将比执行非原子的长得多。如果您多次调用某个方法中的某个属性,那么在您的情况下,合理的做法是使用局部变量
Call*initedCall=appDelegate.userInitiatedCall
。检查声明,如果可能的话,检查在ifs中多次使用的所有属性的实现。如果会有一些复杂的或线程安全的(原子的)建议,那将是有意义的。@Zapko…一些很棒的建议。我尝试了setNeedsDisplay、alpha和addSubview,但仍然得到相同的响应。另外,我没有查找appDel.foo.bar,而是传入一个userInfo字典,其中包含调用状态更改时发布的通知。仍然具有非常一致的~7秒延迟。我明确地追踪到了if语句,它询问callState==ctcallstatedconnected。如果我将条件更改为if(1==1),则所有内容都会完美地显示/隐藏。奇怪的我坚持您应该尝试声明本地var
NSString*callState=appDelegate.userInitiatedCall.callState
。顺便说一下,CTCallStateDisconnected是string。如果你检查一下strin会更好