{"id":14521,"date":"2016-05-12T12:00:04","date_gmt":"2016-05-12T16:00:04","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=14521"},"modified":"2016-05-14T20:14:12","modified_gmt":"2016-05-15T00:14:12","slug":"beware-the-uikit-visitors","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2016\/05\/12\/beware-the-uikit-visitors\/","title":{"rendered":"Beware the UIKit Visitors"},"content":{"rendered":"<p><a href=\"https:\/\/twitter.com\/rpy\/status\/729550705137090560?ref_src=twsrc%5Etfw\">Rupert H<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/rpy\/status\/729550705137090560?ref_src=twsrc%5Etfw\"><p>My discovery for the day is iOS has an O(n^2) cost to add a subview so never have too many subviews on a view or performance goes to shit<\/p><\/blockquote>\n<p><a href=\"https:\/\/twitter.com\/wooji\/status\/729645885605466112\">Wooji Juice<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/wooji\/status\/729645885605466112\"><p>I&rsquo;ve found that setting tintColor on the view manually before adding it to the hierarchy helps a lot.<\/p><\/blockquote>\n<p><a href=\"http:\/\/blog.benjamin-encz.de\/post\/disassembling-uikit-tintcolor-visitor\/\">Benjamin Encz<\/a>:<\/p>\n<blockquote cite=\"http:\/\/blog.benjamin-encz.de\/post\/disassembling-uikit-tintcolor-visitor\/\">\n<p>This means, that as soon as a <code>_UITintColorVisitor<\/code> has an original visited view (which is true after it visited its first view), the outlined code checks if the <code>subviews<\/code> array of the <code>originalVisitedView<\/code> contains the currently visited view. This check scans the full array of subviews; in cases where the <code>originalVisitedView<\/code> is our root view, the cost of this operation grows linearly with the amount of added subviews.<\/p>\n<p>[&#8230;]<\/p>\n<p>Once we know the memory address offset we can create breakpoints in lldb based on addresses in Hopper.<\/p>\n<p>[&#8230;]<\/p>\n<p>With this approach I identified that with the current sample code, <code>eax<\/code> <strong>always refers to the root view<\/strong>. This means we are iterating over all subviews of the root view, N times for each subview that is added.<\/p>\n<\/blockquote>\n<p>Update (2016-05-14): See also: <a href=\"https:\/\/news.ycombinator.com\/item?id=11694507\">Hacker News<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Rupert H: My discovery for the day is iOS has an O(n^2) cost to add a subview so never have too many subviews on a view or performance goes to shit Wooji Juice: I&rsquo;ve found that setting tintColor on the view manually before adding it to the hierarchy helps a lot. Benjamin Encz: This means, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[770,69,763,31,1137,317,138,71],"class_list":["post-14521","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-assembly-language","tag-cocoa","tag-hopper","tag-ios","tag-ios-9","tag-lldb","tag-optimization","tag-programming"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/14521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=14521"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/14521\/revisions"}],"predecessor-version":[{"id":14546,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/14521\/revisions\/14546"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=14521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=14521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=14521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}