未捕获的异常:CALayer 位置在做动画时包含 NaN

Posted

技术标签:

【中文标题】未捕获的异常:CALayer 位置在做动画时包含 NaN【英文标题】:Uncaught exception: CALayer position contains NaN when doing animation 【发布时间】:2014-04-08 11:27:41 【问题描述】:

当我在 iPad 上运行时,我的应用程序中出现此错误:

未捕获的异常:CALayer 位置包含 NaN

相同的代码在 iPhone 上也能正常工作。

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views

    AnnotationView *aV;

    for (aV in views) 
        // Don't pin drop if annotation is user location
        if ([aV.annotation isKindOfClass:[MKUserLocation class]]) 
            continue;
        

        // Check if current annotation is inside visible map rect, else go to next one
        MKMapPoint point =  MKMapPointForCoordinate(aV.annotation.coordinate);
        if (!MKMapRectContainsPoint(mapViewResult.visibleMapRect, point)) 
            continue;
        

        CGRect endFrame = aV.frame;

        // Move annotation out of view
        // I checked here, CGRectEmpty returns true here

        aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - self.view.frame.size.height, aV.frame.size.width, aV.frame.size.height);

        // Animate drop
        [UIView animateWithDuration:0.5 delay:0.04*[views indexOfObject:aV] options: UIViewAnimationOptionCurveLinear animations:^

            aV.frame = endFrame;

            // Animate squash
        completion:^(BOOL finished)
            if (finished) 
                [UIView animateWithDuration:0.05 animations:^
                    aV.transform = CGAffineTransformMakeScale(1.0, 0.8);

                completion:^(BOOL finished)
                    if (finished) 
                        [UIView animateWithDuration:0.1 animations:^
                            aV.transform = CGAffineTransformIdentity;
                        ];
                    
                ];
            
        ];
    

我知道,分配的框架包含NaN 值,我用CGRectEmpty 函数检查了这个并将该框架设置为CGRectZero,但它不会工作。

我从这里得到了这个工作代码,https://***.com/a/7045916/1603234

回溯/调试日志

*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [594.947 nan]'
*** First throw call stack:
(
    0   CoreFoundation                      0x048551e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x034ad8e5 objc_exception_throw + 44
    2   CoreFoundation                      0x04854fbb +[NSException raise:format:] + 139
    3   QuartzCore                          0x01a1be1a _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 190
    4   QuartzCore                          0x01a1bfd9 -[CALayer setPosition:] + 68
    5   QuartzCore                          0x01a1c6df -[CALayer setFrame:] + 799
    6   UIKit                               0x01fbbb4d -[UIView(Geometry) setFrame:] + 302
    7   MyAppName                           0x0026b025 -[ResultMapViewController mapView:didAddAnnotationViews:] + 2133
    8   MapKit                              0x01e0449b -[MKMapView annotationManager:didAddAnnotationRepresentations:] + 272
    9   MapKit                              0x01e3b53c -[MKAnnotationManager updateVisibleAnnotations] + 2052
    10  Foundation                          0x02ed6de7 __NSFireTimer + 97
    11  CoreFoundation                      0x04813ac6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
    12  CoreFoundation                      0x048134ad __CFRunLoopDoTimer + 1181
    13  CoreFoundation                      0x047fb538 __CFRunLoopRun + 1816
    14  CoreFoundation                      0x047fa9d3 CFRunLoopRunSpecific + 467
    15  CoreFoundation                      0x047fa7eb CFRunLoopRunInMode + 123
    16  GraphicsServices                    0x03ccd5ee GSEventRunModal + 192
    17  GraphicsServices                    0x03ccd42b GSEventRun + 104
    18  UIKit                               0x01f60f9b UIApplicationMain + 1225
    19  MyAppName                           0x0001ba3d main + 141
    20  MyAppName                           0x000027e5 start + 53
)
libc++abi.dylib: terminating with uncaught exception of type NSException

【问题讨论】:

添加异常断点。进入“Breakpoint Navigator”,点击左下角的“+”,选择“Add Exception Breakpoint”。运行应用程序以获取断点。当您点击异常断点时,单击调试继续几次,您将获得回溯和更多错误信息。发布那个和 Xcode/Debugger 消息的精确副本。 我已经看到这种行为具有非常小的时间间隔 - 或者非常动画增量 - 我怀疑最终结果是一个值非常小以至于它标准化为零,然后用于除法。 【参考方案1】:

天哪!我不知道我会犯这种“愚蠢”的错误。

是的,有问题的句子相同的代码在 iPhone 上运行良好。我收到错误 CALayer position contains NaN,因为在我正在计算的自定义 - (AnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id ) annotation 方法中

annotationView.layer.anchorPoint = CGPointMake(0.5, 1.0 - (diffFromBottom * 1.0)/annotationView.image.size.height);

annotationView.image 是空白的,因为我忘记在 iPad 项目中添加 pin 图像。它在 iPhone 代码中。所以它被零(0)除并导致错误。

我放了断点,然后用NSLog打印就知道了,

1.0 - (diffFromBottom * 1.0)/annotationView.image.size.height 的值已打印,-inf。这是导致应用崩溃的原因。

基本上,如果您将执行除以无穷大或零,则会发生此错误,因此每当您遇到此类错误时,首先查看执行除法运算的代码。

【讨论】:

形成我的案例“nan”是因为除零值“nan”值来了。可能这对你有帮助。

以上是关于未捕获的异常:CALayer 位置在做动画时包含 NaN的主要内容,如果未能解决你的问题,请参考以下文章

由于未捕获的异常“CALayerInvalidGeometry”而终止应用程序,原因:“CALayer bounds contains NaN: [0 nan; 280 524]'

随机“CALayerInvalidGeometry 原因:CALayer 位置包含 NaN”异常

随机“CALayerInvalidGeometry原因:CALayer位置包含NaN”异常

UIScrollView CALayer 位置包含 NaN

动画期间无法获取 CALayer 的当前位置

UIVIew/CALayer 动画期间的回调