Iphone 多模式视图转换崩溃应用程序

Iphone 多模式视图转换崩溃应用程序,iphone,cocoa-touch,Iphone,Cocoa Touch,我希望按顺序显示多模式视图(例如,从图像选择器中选择图片后显示确认页面)。我的问题是,在随后的步骤中毫不延迟地进行解雇和演示的动画总是会使应用程序崩溃,并出现EXC\u BAD\u访问 我假设问题在于CoreAnimation无法区分这两个过渡,并且无法正确检测第一个过渡是否结束 到目前为止,我的工作是引入1段延迟,这似乎解决了问题。然而,我认为这使得代码有点脆弱。还有其他解决办法吗 这是UIKit中的错误吗?我是否应该提交错误报告 示例代码 下面是一个重现崩溃的简单案例: 创建一个新的基于视图

我希望按顺序显示多模式视图(例如,从图像选择器中选择图片后显示确认页面)。我的问题是,在随后的步骤中毫不延迟地进行解雇和演示的动画总是会使应用程序崩溃,并出现
EXC\u BAD\u访问

我假设问题在于
CoreAnimation
无法区分这两个过渡,并且无法正确检测第一个过渡是否结束

到目前为止,我的工作是引入1段延迟,这似乎解决了问题。然而,我认为这使得代码有点脆弱。还有其他解决办法吗

这是UIKit中的错误吗?我是否应该提交错误报告

示例代码

下面是一个重现崩溃的简单案例:

  • 创建一个新的基于视图的项目,使用以下类作为主控制器的实现

  • 显示图像选择器视图时,点击“取消”

  • 预期行为:由于在
    viewdideappear
    中的后续调用,选择器视图被取消并再次显示

    实际行为:它与下面显示的堆栈跟踪一起崩溃

    代码:

    崩溃堆栈跟踪:

    #0 0x30b43212 in -[UIWindowController transitionViewDidComplete:fromView:toView:] #1 0x3095828e in -[UITransitionView notifyDidCompleteTransition:] #2 0x3091af0d in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] #3 0x3091ad7c in -[UIViewAnimationState animationDidStop:finished:] #4 0x00b54331 in run_animation_callbacks #5 0x00b54109 in CA::timer_callback #6 0x302454a0 in CFRunLoopRunSpecific #7 0x30244628 in CFRunLoopRunInMode #8 0x32044c31 in GSEventRunModal #9 0x32044cf6 in GSEventRun #10 0x309021ee in UIApplicationMain #11 0x00002794 in main at main.m:14 #0 0x30b43212 in-[UIWindowController转换视图完成:从视图:到视图:] #1 0x3095828e位于-[UITransitionView notifyDidCompleteTransition:] #2 0x3091af0d in-[UIViewAnimationState sendDelegateAnimationDidStop:finished:] #3 0x3091ad7c in-[UIViewAnimationState animationDidStop:finished:] #4 0x00b54331在运行\u动画\u回调中 #CA::timer\u回调中的5 0x00b54109 #cfrunloopspecific中的6 0x302454a0 #cfrunlooprunin模式下的7 0x30244628 #GSEventRunModal中的8 0x32044c31 #GSEventRun中的9 0x32044cf6 #UIApplicationMain中的10 0x309021E #11 0x00002794在主管道的主管道中。m:14
    您可能需要让动画上下文完成。正如你已经发现的

    [自执行选择器:@selector(showmodel),对象:nil afterDelay:1]

    这是可行的,但显然,延迟是不好的,所以要这样做:

    [self performSelector:@selector(showModal) withObject:nil afterDelay:0.0];
    
    当您使用afterDelay:0.0时,它不会直接调用选择器,而是在runloop上对调用进行排队,这样,您的所有状态(自动释放池、动画上下文等)都可以正确运行,然后在runloop开始处理事件时立即调用

    有一个问题可能是,用户可以通过点击屏幕来启动UIEvents,但您可以通过在动画开始之前调用它来解决这一问题

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
    
    一旦你在屏幕上有了最终的模式

    [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    

    通常情况下,在设置快速转换动画时,您希望使用UI交互。

    +1表示
    beginIgnoringInteractionEvents
    suggestion。我以前从来都不知道。
    [[UIApplication sharedApplication] endIgnoringInteractionEvents];