diff --git a/Source/Private/_ASCoreAnimationExtras.mm b/Source/Private/_ASCoreAnimationExtras.mm index bac2f44ba..b55bd6442 100644 --- a/Source/Private/_ASCoreAnimationExtras.mm +++ b/Source/Private/_ASCoreAnimationExtras.mm @@ -62,42 +62,58 @@ void ASDisplayNodeSetResizableContents(id obj, UIImage *ima NSString *const string; }; -static const struct _UIContentModeStringLUTEntry UIContentModeCAGravityLUT[] = { - {UIViewContentModeScaleToFill, kCAGravityResize}, - {UIViewContentModeScaleAspectFit, kCAGravityResizeAspect}, - {UIViewContentModeScaleAspectFill, kCAGravityResizeAspectFill}, - {UIViewContentModeCenter, kCAGravityCenter}, - {UIViewContentModeTop, kCAGravityBottom}, - {UIViewContentModeBottom, kCAGravityTop}, - {UIViewContentModeLeft, kCAGravityLeft}, - {UIViewContentModeRight, kCAGravityRight}, - {UIViewContentModeTopLeft, kCAGravityBottomLeft}, - {UIViewContentModeTopRight, kCAGravityBottomRight}, - {UIViewContentModeBottomLeft, kCAGravityTopLeft}, - {UIViewContentModeBottomRight, kCAGravityTopRight}, -}; +static const _UIContentModeStringLUTEntry *UIContentModeCAGravityLUT(size_t *count) +{ + // Initialize this in a function (instead of at file level) to avoid + // startup initialization time. + static const _UIContentModeStringLUTEntry sUIContentModeCAGravityLUT[] = { + {UIViewContentModeScaleToFill, kCAGravityResize}, + {UIViewContentModeScaleAspectFit, kCAGravityResizeAspect}, + {UIViewContentModeScaleAspectFill, kCAGravityResizeAspectFill}, + {UIViewContentModeCenter, kCAGravityCenter}, + {UIViewContentModeTop, kCAGravityBottom}, + {UIViewContentModeBottom, kCAGravityTop}, + {UIViewContentModeLeft, kCAGravityLeft}, + {UIViewContentModeRight, kCAGravityRight}, + {UIViewContentModeTopLeft, kCAGravityBottomLeft}, + {UIViewContentModeTopRight, kCAGravityBottomRight}, + {UIViewContentModeBottomLeft, kCAGravityTopLeft}, + {UIViewContentModeBottomRight, kCAGravityTopRight}, + }; + *count = sizeof(sUIContentModeCAGravityLUT) / sizeof(sUIContentModeCAGravityLUT[0]); + return sUIContentModeCAGravityLUT; +} -static const struct _UIContentModeStringLUTEntry UIContentModeDescriptionLUT[] = { - {UIViewContentModeScaleToFill, @"scaleToFill"}, - {UIViewContentModeScaleAspectFit, @"aspectFit"}, - {UIViewContentModeScaleAspectFill, @"aspectFill"}, - {UIViewContentModeRedraw, @"redraw"}, - {UIViewContentModeCenter, @"center"}, - {UIViewContentModeTop, @"top"}, - {UIViewContentModeBottom, @"bottom"}, - {UIViewContentModeLeft, @"left"}, - {UIViewContentModeRight, @"right"}, - {UIViewContentModeTopLeft, @"topLeft"}, - {UIViewContentModeTopRight, @"topRight"}, - {UIViewContentModeBottomLeft, @"bottomLeft"}, - {UIViewContentModeBottomRight, @"bottomRight"}, -}; +static const _UIContentModeStringLUTEntry *UIContentModeDescriptionLUT(size_t *count) +{ + // Initialize this in a function (instead of at file level) to avoid + // startup initialization time. + static const _UIContentModeStringLUTEntry sUIContentModeDescriptionLUT[] = { + {UIViewContentModeScaleToFill, @"scaleToFill"}, + {UIViewContentModeScaleAspectFit, @"aspectFit"}, + {UIViewContentModeScaleAspectFill, @"aspectFill"}, + {UIViewContentModeRedraw, @"redraw"}, + {UIViewContentModeCenter, @"center"}, + {UIViewContentModeTop, @"top"}, + {UIViewContentModeBottom, @"bottom"}, + {UIViewContentModeLeft, @"left"}, + {UIViewContentModeRight, @"right"}, + {UIViewContentModeTopLeft, @"topLeft"}, + {UIViewContentModeTopRight, @"topRight"}, + {UIViewContentModeBottomLeft, @"bottomLeft"}, + {UIViewContentModeBottomRight, @"bottomRight"}, + }; + *count = sizeof(sUIContentModeDescriptionLUT) / sizeof(sUIContentModeDescriptionLUT[0]); + return sUIContentModeDescriptionLUT; +} NSString *ASDisplayNodeNSStringFromUIContentMode(UIViewContentMode contentMode) { - for (let &e : UIContentModeDescriptionLUT) { - if (e.contentMode == contentMode) { - return e.string; + size_t lutSize; + const _UIContentModeStringLUTEntry *lut = UIContentModeDescriptionLUT(&lutSize); + for (size_t i = 0; i < lutSize; ++i) { + if (lut[i].contentMode == contentMode) { + return lut[i].string; } } return [NSString stringWithFormat:@"%d", (int)contentMode]; @@ -105,9 +121,11 @@ void ASDisplayNodeSetResizableContents(id obj, UIImage *ima UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string) { - for (let &e : UIContentModeDescriptionLUT) { - if (ASObjectIsEqual(e.string, string)) { - return e.contentMode; + size_t lutSize; + const _UIContentModeStringLUTEntry *lut = UIContentModeDescriptionLUT(&lutSize); + for (size_t i = 0; i < lutSize; ++i) { + if (ASObjectIsEqual(lut[i].string, string)) { + return lut[i].contentMode; } } return UIViewContentModeScaleToFill; @@ -115,9 +133,11 @@ UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string) NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIViewContentMode contentMode) { - for (let &e : UIContentModeCAGravityLUT) { - if (e.contentMode == contentMode) { - return e.string; + size_t lutSize; + const _UIContentModeStringLUTEntry *lut = UIContentModeCAGravityLUT(&lutSize); + for (size_t i = 0; i < lutSize; ++i) { + if (lut[i].contentMode == contentMode) { + return lut[i].string; } } ASDisplayNodeCAssert(contentMode == UIViewContentModeRedraw, @"Encountered an unknown contentMode %ld. Is this a new version of iOS?", (long)contentMode); @@ -137,9 +157,11 @@ UIViewContentMode ASDisplayNodeUIContentModeFromCAContentsGravity(NSString *cons return cachedModes[foundCacheIndex]; } - for (let &e : UIContentModeCAGravityLUT) { - if (ASObjectIsEqual(e.string, contentsGravity)) { - UIViewContentMode foundContentMode = e.contentMode; + size_t lutSize; + const _UIContentModeStringLUTEntry *lut = UIContentModeCAGravityLUT(&lutSize); + for (size_t i = 0; i < lutSize; ++i) { + if (ASObjectIsEqual(lut[i].string, contentsGravity)) { + UIViewContentMode foundContentMode = lut[i].contentMode; if (currentCacheIndex < ContentModeCacheSize) { // Cache the input value. This is almost always a different pointer than in our LUT and will frequently