{"action":"created","issue":{"url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/issues/565","labels_url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/issues/565/labels{/name}","comments_url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/issues/565/comments","events_url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/issues/565/events","html_url":"https://github.com/TTTAttributedLabel/TTTAttributedLabel/pull/565","id":98416636,"number":565,"title":"Fix UI hang due to contention between OS drawing and too many setText: threads trying to dispatch_sync to main queue.","user":{"login":"benshan","id":1281593,"avatar_url":"https://avatars.githubusercontent.com/u/1281593?v=3","gravatar_id":"","url":"https://api.github.com/users/benshan","html_url":"https://github.com/benshan","followers_url":"https://api.github.com/users/benshan/followers","following_url":"https://api.github.com/users/benshan/following{/other_user}","gists_url":"https://api.github.com/users/benshan/gists{/gist_id}","starred_url":"https://api.github.com/users/benshan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benshan/subscriptions","organizations_url":"https://api.github.com/users/benshan/orgs","repos_url":"https://api.github.com/users/benshan/repos","events_url":"https://api.github.com/users/benshan/events{/privacy}","received_events_url":"https://api.github.com/users/benshan/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-07-31T15:45:53Z","updated_at":"2015-09-12T22:35:27Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/pulls/565","html_url":"https://github.com/TTTAttributedLabel/TTTAttributedLabel/pull/565","diff_url":"https://github.com/TTTAttributedLabel/TTTAttributedLabel/pull/565.diff","patch_url":"https://github.com/TTTAttributedLabel/TTTAttributedLabel/pull/565.patch"},"body":"Seen on iphone5/ios8.4 with tableview that has several dozen cells containing attributed string like this:\r\n\r\n```\r\nYour client job number 11884 completed with status ABORTED. See https://blah.com:8443/job/client/11884/ for more details. Respond to this message to update build description.{\r\n    CTForegroundColor = \"UIDeviceRGBColorSpace 0.384314 0.392157 0.411765 1\";\r\n    NSFont = \"<UICTFont: 0x177d5c00> font-family: \\\"HelveticaNeue-Light\\\"; font-weight: normal; font-style: normal; font-size: 16.00pt\";\r\n    NSKern = 0;\r\n    NSParagraphStyle = \"Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 20.0128/20.0128, LineHeightMultiple 1.06, LineBreakMode 0, Tabs (\\n    28L,\\n    56L,\\n    84L,\\n    112L,\\n    140L,\\n    168L,\\n    196L,\\n    224L,\\n    252L,\\n    280L,\\n    308L,\\n    336L\\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0, HeaderLevel 0\";\r\n}\r\n```\r\n\r\nDebugger shows many dozen invocations to setText: waiting in the dispatch_sync.\r\n\r\n```\r\n* thread #73: tid = 0x37977a, 0x327ba4c4 libsystem_kernel.dylib`semaphore_wait_trap + 8, queue = 'com.apple.root.default-qos'\r\n  * frame #0: 0x327ba4c4 libsystem_kernel.dylib`semaphore_wait_trap + 8\r\n    frame #1: 0x32846434 libsystem_platform.dylib`_os_semaphore_wait + 12\r\n    frame #2: 0x021f6bd6 libdispatch.dylib`_dispatch_barrier_sync_f_slow + 438\r\n    frame #3: 0x0022aba0 app`__30-[TTTAttributedLabel setText:]_block_invoke(.block_descriptor=<unavailable>) + 436 at TTTAttributedLabel.m:1125\r\n    frame #4: 0x021ef172 libdispatch.dylib`_dispatch_call_block_and_release + 10\r\n    frame #5: 0x021f9c38 libdispatch.dylib`_dispatch_root_queue_drain + 1612\r\n    frame #6: 0x021fae18 libdispatch.dylib`_dispatch_worker_thread3 + 100\r\n    frame #7: 0x32849dc0 libsystem_pthread.dylib`_pthread_wqthread + 668\r\n    frame #8: 0x32849b14 libsystem_pthread.dylib`start_wqthread + 8\r\n```\r\n\r\nMain thread is here:\r\n\r\n```\r\n* thread #1: tid = 0x379611, 0x327ba4c4 libsystem_kernel.dylib`semaphore_wait_trap + 8, name = 'Main', queue = 'com.apple.main-thread', stop reason = signal SIGSTOP\r\n  * frame #0: 0x327ba4c4 libsystem_kernel.dylib`semaphore_wait_trap + 8\r\n    frame #1: 0x021fb298 libdispatch.dylib`_dispatch_group_wait_slow + 204\r\n    frame #2: 0x29aec336 CoreUI`-[_CSIRenditionBlockData expandCSIBitmapData:fromSlice:makeReadOnly:] + 594\r\n    frame #3: 0x29af014e CoreUI`csiCompressImageProviderCopyImageBlockSetWithOptions + 1114\r\n    frame #4: 0x23cee232 CoreGraphics`CGImageProviderCopyImageBlockSetWithOptions + 178\r\n    frame #5: 0x26b641a4 QuartzCore`CA::Render::create_image(CGImage*, CGColorSpace*, unsigned int) + 716\r\n    frame #6: 0x26b635fe QuartzCore`CA::Render::copy_image(CGImage*, CGColorSpace*, unsigned int, double) + 314\r\n    frame #7: 0x26b63ec6 QuartzCore`CA::Render::prepare_image(CGImage*, CGColorSpace*, unsigned int, double) + 18\r\n    frame #8: 0x26b378dc QuartzCore`CA::Layer::prepare_commit(CA::Transaction*) + 368\r\n    frame #9: 0x26b36d88 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 232\r\n    frame #10: 0x26b36b6e QuartzCore`CA::Transaction::commit() + 434\r\n    frame #11: 0x26b30848 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 56\r\n    frame #12: 0x23a73fec CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20\r\n    frame #13: 0x23a716aa CoreFoundation`__CFRunLoopDoObservers + 278\r\n    frame #14: 0x23a71ab2 CoreFoundation`__CFRunLoopRun + 914\r\n    frame #15: 0x239be200 CoreFoundation`CFRunLoopRunSpecific + 476\r\n    frame #16: 0x239be012 CoreFoundation`CFRunLoopRunInMode + 106\r\n    frame #17: 0x2b48f200 GraphicsServices`GSEventRunModal + 136\r\n    frame #18: 0x2718aa08 UIKit`UIApplicationMain + 1440\r\n    frame #19: 0x00021f8c app`main(argc=3, argv=0x01f50a30) + 272 at main.mm:19\r\n```"},"comment":{"url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/issues/comments/139825465","html_url":"https://github.com/TTTAttributedLabel/TTTAttributedLabel/pull/565#issuecomment-139825465","issue_url":"https://api.github.com/repos/TTTAttributedLabel/TTTAttributedLabel/issues/565","id":139825465,"user":{"login":"getaaron","id":789577,"avatar_url":"https://avatars.githubusercontent.com/u/789577?v=3","gravatar_id":"","url":"https://api.github.com/users/getaaron","html_url":"https://github.com/getaaron","followers_url":"https://api.github.com/users/getaaron/followers","following_url":"https://api.github.com/users/getaaron/following{/other_user}","gists_url":"https://api.github.com/users/getaaron/gists{/gist_id}","starred_url":"https://api.github.com/users/getaaron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getaaron/subscriptions","organizations_url":"https://api.github.com/users/getaaron/orgs","repos_url":"https://api.github.com/users/getaaron/repos","events_url":"https://api.github.com/users/getaaron/events{/privacy}","received_events_url":"https://api.github.com/users/getaaron/received_events","type":"User","site_admin":false},"created_at":"2015-09-12T22:35:27Z","updated_at":"2015-09-12T22:35:27Z","body":"I think the change to `dispatch_sync` may have been a typo in https://github.com/TTTAttributedLabel/TTTAttributedLabel/commit/974a531ebc3bb95634e2d9584572a4f48b8f991e. I don't see any reason not to use `dispatch_async` in this case.\r\n\r\n@benshan Can you please merge `master` into your branch? If possible, can you please write either (1) an automated test that fails with the current code, but passes with yours, or (2) a performance test demonstrating improvement?"}}