UITintColorVisitor causes exponentially worsening performance when adding subviews
Originator: | xenadu | ||
Number: | rdar://25934331 | Date Originated: | 26-Apr-2016 10:37 AM |
Status: | Open | Resolved: | |
Product: | iOS SDK | Product Version: | 9.0 |
Classification: | Reproducible: | Yes |
Summary: When adding subviews to a view that obtains its tint color from the window or a parent view performance gets exponentially worse the more subviews you add. When adding 6000 subviews execution takes over 10 minutes in the following method chain: In _postMovedFromSuperview, _UIViewVisitorRecursivelyEntertainDescendingVisitors, _UITintColorVisitor.visitView, checking NSArray.containsObject. It appears UIKit is visiting all sibling views to set their tintColor when only a single sibling is added. Here is a really simple sample project demonstrating the problem. If you tap the Custom Tint Color button it will take several minutes to run. If you tap the No Tint Color button the subviews are added so quickly you might miss it. The identical code is running in both cases, the only difference is whether the application UIWindow has a tintColor set. Steps to Reproduce: Set window tintColor to a non-default color Create a subview class Add 6000 subviews to the parent view Observe exponentially decreasing performance as UITintColorVisitor continuously re-scans the growing array. Expected Results: Performance should not get exponentially worse with more subviews Actual Results: Performance gets exponentially worse Version: iOS 9.3, Xcode 7.3 Notes: A temporary workaround is to explicitly set the tintColor on all subviews but that defeats the purpose of tintColor's inheritance system.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
The performance is improved on iOS 10.
It takes about 5-6 seconds to add 6000 subviews with a custom tint color set compared to less than 1 second with no custom tint color.
I would still consider this an undesirable behavior on the part of UIKit especially for a bunch of views that don't have children and don't care about the tint color. I would expect the tint color to be lazily resolved when needed, not pushed every time subviews are added.
For that reason I still consider this an open bug.