記錄一個問題, CALayer renderInContext: 在 iOS 8 或者 iOS9 上可能會導致崩潰煌抒。
復現(xiàn)步驟,當對一個 view 的 layer 執(zhí)行 renderInContext: 方法時蕾久,如果該 view 的 layer 樹的子圖層樹中有 frame 為 CGRectNULL 或者 position (frame.origin.x / frame.origin.y)中有 INFINITY 的時候婉宰, 會導致崩潰歌豺。
在 iOS 8 上會導致:
Assertion failed: (transform_is_valid(m)), function CGPathRef CGPathCreateWithRect(CGRect, const CGAffineTransform *), file Paths/CGPath.cc, line 179.
在 iOS 9 上會導致:
2017-09-13 16:34:58.335 UIKitTest[9443:271781] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'sublayer with non-finite position [inf inf]' *** First throw call stack: ( 0 CoreFoundation 0x000000010bf15d85 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010b989deb objc_exception_throw + 48 2 CoreFoundation 0x000000010bf15cbd +[NSException raise:format:] + 205 3 QuartzCore 0x000000010ca8a9ee -[CALayer _renderSublayersInContext:] + 550 4 QuartzCore 0x000000010ca88dee -[CALayer renderInContext:] + 990 5 QuartzCore 0x000000010ca8a9be -[CALayer _renderSublayersInContext:] + 502 6 QuartzCore 0x000000010ca88dee -[CALayer renderInContext:] + 990 7 QuartzCore 0x000000010ca8a9be -[CALayer _renderSublayersInContext:] + 502 8 QuartzCore 0x000000010ca88dee -[CALayer renderInContext:] + 990 ...
如果對 UIView 做截圖,可以使用如下方法心包,自測不會 Crash.
-[UIView drawViewHierarchyInRect:appDelegate.window.bounds afterScreenUpdates:];
總結(jié): 平時開發(fā)時, 我們通過計算馒铃,很難會出現(xiàn) CGRectNULL 或者 Position 中出現(xiàn) INFINITY 的情況蟹腾, 除非通過 CGRectDivide 等調(diào)用, 可能會返回一個 CGRectNULL 但是這個時候区宇,我們一般會對這個返回值做測試娃殖, 而 INFINITY 的話, 浮點數(shù)溢出可能產(chǎn)生這個值议谷。
旁注: 如果我們計算 frame 時炉爆,設置了 NAN 或者通過某種方式產(chǎn)生了包含 NAN 為成員變量的 CGRect 結(jié)構體,那么在添加到 view 視圖樹 或者 layer 圖層樹中卧晓,會直接導致崩潰芬首,這個情況比較直觀。記錄一下對這些邊界值的測試逼裆。