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工作发生的主队列。威利。隐藏/显示视图的过程非常快。问题在于视图及其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),则所有内容都会完美地显示/隐藏。奇怪的我坚持您应该尝试声明本地varNSString*callState=appDelegate.userInitiatedCall.callState
。顺便说一下,CTCallStateDisconnected是string。如果你检查一下strin会更好