diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 102be6d4e..2f34dde60 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -63,7 +63,6 @@ #define ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR 0 static ASDisplayNodeNonFatalErrorBlock _nonFatalErrorBlock = nil; -NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority; // Forward declare CALayerDelegate protocol as the iOS 10 SDK moves CALayerDelegate from an informal delegate to a protocol. // We have to forward declare the protocol as this place otherwise it will not compile compiling with an Base SDK < iOS 10 @@ -272,7 +271,7 @@ - (void)_initializeInstance _contentsScaleForDisplay = ASScreenScale(); - _drawingPriority = ASDefaultDrawingPriority; + _drawingPriority = ASDefaultTransactionPriority; _primitiveTraitCollection = ASPrimitiveTraitCollectionMakeDefault(); diff --git a/Source/ASImageNode+AnimatedImage.mm b/Source/ASImageNode+AnimatedImage.mm index febbb725e..87680f25c 100644 --- a/Source/ASImageNode+AnimatedImage.mm +++ b/Source/ASImageNode+AnimatedImage.mm @@ -36,7 +36,6 @@ @interface ASNetworkImageNode (Private) - (void)_locked_setDefaultImage:(UIImage *)image; @end -NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes; @implementation ASImageNode (AnimatedImage) diff --git a/Source/ASTextNode.mm b/Source/ASTextNode.mm index 55c830a2f..27b8964b0 100644 --- a/Source/ASTextNode.mm +++ b/Source/ASTextNode.mm @@ -203,7 +203,14 @@ @implementation ASTextNode { } @dynamic placeholderEnabled; -static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; +static NSArray *DefaultLinkAttributeNames() { + static NSArray *names; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + names = @[ NSLinkAttributeName ]; + }); + return names; +} - (instancetype)init { @@ -224,7 +231,7 @@ - (instancetype)init self.opaque = NO; self.backgroundColor = [UIColor clearColor]; - self.linkAttributeNames = DefaultLinkAttributeNames; + self.linkAttributeNames = DefaultLinkAttributeNames(); // Accessibility self.isAccessibilityElement = YES; diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 53eec8029..0fab91149 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -92,7 +92,14 @@ @implementation ASTextNode2 { } @dynamic placeholderEnabled; -static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; +static NSArray *DefaultLinkAttributeNames() { + static NSArray *names; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + names = @[ NSLinkAttributeName ]; + }); + return names; +} - (instancetype)init { @@ -113,9 +120,9 @@ - (instancetype)init // The common case is for a text node to be non-opaque and blended over some background. self.opaque = NO; self.backgroundColor = [UIColor clearColor]; - - self.linkAttributeNames = DefaultLinkAttributeNames; - + + self.linkAttributeNames = DefaultLinkAttributeNames(); + // Accessibility self.isAccessibilityElement = YES; self.accessibilityTraits = UIAccessibilityTraitStaticText; diff --git a/Source/Details/ASBasicImageDownloader.mm b/Source/Details/ASBasicImageDownloader.mm index bdb73b92a..ea96869f2 100644 --- a/Source/Details/ASBasicImageDownloader.mm +++ b/Source/Details/ASBasicImageDownloader.mm @@ -183,14 +183,18 @@ @interface NSURLRequest (ASBasicImageDownloader) @end @implementation NSURLRequest (ASBasicImageDownloader) -static const char *kContextKey = NSStringFromClass(ASBasicImageDownloaderContext.class).UTF8String; + +static const void *ContextKey() { + return @selector(asyncdisplaykit_context); +} + - (void)setAsyncdisplaykit_context:(ASBasicImageDownloaderContext *)asyncdisplaykit_context { - objc_setAssociatedObject(self, kContextKey, asyncdisplaykit_context, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(self, ContextKey(), asyncdisplaykit_context, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (ASBasicImageDownloader *)asyncdisplaykit_context { - return objc_getAssociatedObject(self, kContextKey); + return objc_getAssociatedObject(self, ContextKey()); } @end diff --git a/Source/Private/ASImageNode+AnimatedImagePrivate.h b/Source/Private/ASImageNode+AnimatedImagePrivate.h index f77ee1f9b..b478d4f47 100644 --- a/Source/Private/ASImageNode+AnimatedImagePrivate.h +++ b/Source/Private/ASImageNode+AnimatedImagePrivate.h @@ -17,7 +17,7 @@ #import -extern NSString *const ASAnimatedImageDefaultRunLoopMode; +#define ASAnimatedImageDefaultRunLoopMode NSRunLoopCommonModes @interface ASImageNode () { diff --git a/Source/Private/_ASCoreAnimationExtras.mm b/Source/Private/_ASCoreAnimationExtras.mm index 65172962e..699a15db3 100644 --- a/Source/Private/_ASCoreAnimationExtras.mm +++ b/Source/Private/_ASCoreAnimationExtras.mm @@ -65,42 +65,58 @@ extern void ASDisplayNodeSetResizableContents(id obj, UIIma 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 (int i=0; i< ARRAY_COUNT(UIContentModeDescriptionLUT); i++) { - if (UIContentModeDescriptionLUT[i].contentMode == contentMode) { - return UIContentModeDescriptionLUT[i].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]; @@ -108,9 +124,11 @@ extern void ASDisplayNodeSetResizableContents(id obj, UIIma UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string) { - for (int i=0; i < ARRAY_COUNT(UIContentModeDescriptionLUT); i++) { - if (ASObjectIsEqual(UIContentModeDescriptionLUT[i].string, string)) { - return UIContentModeDescriptionLUT[i].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; @@ -118,9 +136,11 @@ UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string) NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIViewContentMode contentMode) { - for (int i=0; i < ARRAY_COUNT(UIContentModeCAGravityLUT); i++) { - if (UIContentModeCAGravityLUT[i].contentMode == contentMode) { - return UIContentModeCAGravityLUT[i].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 %zd. Is this a new version of iOS?", contentMode); @@ -140,9 +160,11 @@ UIViewContentMode ASDisplayNodeUIContentModeFromCAContentsGravity(NSString *cons return cachedModes[foundCacheIndex]; } - for (int i = 0; i < ARRAY_COUNT(UIContentModeCAGravityLUT); i++) { - if (ASObjectIsEqual(UIContentModeCAGravityLUT[i].string, contentsGravity)) { - UIViewContentMode foundContentMode = UIContentModeCAGravityLUT[i].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