-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ASPrimitiveTraitCollection] Always treat preferredContentSize as a potential nil #trivial #757
Conversation
Add nil-value checks for preferredContentSizeCategory.
It seems better now when changing device orientation @ypogribnyi. Is there documentation around initializing ASPrimitiveTraitCollection? Might be missing something. We were seeing this on iOS 10 & 11. |
The preferred way to create By the way, why do we expose two trait collections interfaces ( |
Good questions! Based on facebookarchive/AsyncDisplayKit#1592, I think the original reason is to have ASTraitCollection as a friendly object-based API and ASPrimitiveTraitCollection as the internal actual struct that is used throughout the framework. We should at least document this reasoning, and/or move ASPrimitiveTraitCollection to a framework-private interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ypogribnyi Great reasoning on the possibility that ASPrimitiveTraitCollection may be initialized manually, and defend against such case.
@ay8s This PR should mitigate your crash, although I'd suggest to dig a bit deeper into your codebase and fix the root cause (initialize ASPrimitiveTraitCollection using the provided functions or better yet, switch to ASTraitCollection). Let us know what you find!
Source/Details/ASTraitCollection.h
Outdated
@@ -175,7 +181,7 @@ AS_SUBCLASSING_RESTRICTED | |||
@property (nonatomic, assign, readonly) UIUserInterfaceStyle userInterfaceStyle; | |||
#endif | |||
|
|||
@property (nonatomic, assign, readonly) UIContentSizeCategory preferredContentSizeCategory; | |||
@property (nonatomic, assign, readonly) UIContentSizeCategory _Nonnull preferredContentSizeCategory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need _Nonnull
annotations since we already use NS_ASSUME_NONNULL_BEGIN
at the beginning of this file (here). It's always good to be defensive and guard against unexpected values in the implementation though.
Source/Details/ASTraitCollection.m
Outdated
} else { | ||
return AS_UIContentSizeCategoryUnspecified(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, feel free to ignore this: It's a bit shorter to use ternary operator here, i.e:
return sizeCategory ? sizeCategory : AS_UIContentSizeCategoryUnspecified();
Source/Details/ASTraitCollection.m
Outdated
@@ -92,7 +100,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { | |||
.displayGamut = UIDisplayGamutUnspecified, | |||
.userInterfaceIdiom = UIUserInterfaceIdiomUnspecified, | |||
.layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified, | |||
.preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(AS_UIContentSizeCategoryUnspecified()), | |||
.preferredContentSizeCategory = AS_UIContentSizeCategoryUnspecified(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we remove the ASPrimitiveContentSizeCategoryMake
in here. If you read the comment above ASPrimitiveContentSizeCategory
we have to use ASPrimitiveContentSizeCategoryMake
* Mark [ASViewController overrideDisplayTraitsWithWindowSize] as deprecated. Code review changes: * Remove unneeded nonnull annotations * Add null check in ASTraitCollection constructor implementation * Codestyle * Add some documentation about ASPrimitiveTraitCollection vs ASTraitCollection usage
Thanks @ypogribnyi. We don't actually initialize either ASPrimitiveCollectionTraits or ASTraitCollection ourselves. I wonder if this might help with digging into the cause http://crashes.to/s/058c9ea3e54 |
@ay8s, thank you for your input! I finally managed to reproduce the crash. Looks like it occurs in I'm reproducing it on
while having Although having a Anyways, this PR should fix the problem. |
Yup that'd be it! Thanks @ypogribnyi! |
Source/Details/ASTraitCollection.m
Outdated
@@ -32,6 +32,14 @@ ASDISPLAYNODE_INLINE UIContentSizeCategory AS_UIContentSizeCategoryUnspecified() | |||
} | |||
} | |||
|
|||
ASDISPLAYNODE_INLINE ASPrimitiveContentSizeCategory safePrimitiveContentSizeCategory(ASPrimitiveContentSizeCategory sizeCategory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we still should prefix this functions with AS
Source/Details/ASTraitCollection.m
Outdated
@@ -92,7 +100,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { | |||
.displayGamut = UIDisplayGamutUnspecified, | |||
.userInterfaceIdiom = UIUserInterfaceIdiomUnspecified, | |||
.layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified, | |||
.preferredContentSizeCategory = ASPrimitiveContentSizeCategoryMake(AS_UIContentSizeCategoryUnspecified()), | |||
.preferredContentSizeCategory = AS_UIContentSizeCategoryUnspecified(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we remove the ASPrimitiveContentSizeCategoryMake
in here. If you read the comment above ASPrimitiveContentSizeCategory
we have to use ASPrimitiveContentSizeCategoryMake
Source/Details/ASTraitCollection.m
Outdated
@@ -32,6 +32,14 @@ ASDISPLAYNODE_INLINE UIContentSizeCategory AS_UIContentSizeCategoryUnspecified() | |||
} | |||
} | |||
|
|||
ASDISPLAYNODE_INLINE ASPrimitiveContentSizeCategory safePrimitiveContentSizeCategory(ASPrimitiveContentSizeCategory sizeCategory) { | |||
return sizeCategory ? sizeCategory : AS_UIContentSizeCategoryUnspecified(); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in both cases we have to use ASPrimitiveContentSizeCategoryMake(AS_UIContentSizeCategoryUnspecified())
Remove safePrimitiveContentSizeCategory in favour of AS_safeContentSizeCategory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for dropping the ball here, @ypogribnyi. LGTM now. Thanks!
…otential nil #trivial (TextureGroup#757) * Fix ASPrimitiveTraitCollection initialization on iOS 9. Add nil-value checks for preferredContentSizeCategory. * * Mark -[ASTraitCollection init] as deprecated. * Mark [ASViewController overrideDisplayTraitsWithWindowSize] as deprecated. Code review changes: * Remove unneeded nonnull annotations * Add null check in ASTraitCollection constructor implementation * Codestyle * Add some documentation about ASPrimitiveTraitCollection vs ASTraitCollection usage * Rename safeContentSizeCategory to AS_safeContentSizeCategory. Remove safePrimitiveContentSizeCategory in favour of AS_safeContentSizeCategory.
As
ASPrimitiveTraitCollection
is a struct, the application can always initialize it in its own way, without using Texture-provided initialization functions. This may lead topreferredContentSize
field beingnil
, which, in turn, may lead to frustrating crashes when the struct is given to Texture.While simply advising the user to always use the provided initialization functions should solve the problem, it's better to always treat this structure as possibly improperly initialized and guard against
nil
value in this field.Additionally this PR explicitly marks all
UIContentSizeCategory
usage inASTraitCollection
class as non-null.