Skip to content
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

🐞 [Bug] NSAttributedString.DocumentType.html main thread crash #767

Merged
merged 2 commits into from
Jul 30, 2019

Conversation

justinswart
Copy link
Contributor

@justinswart justinswart commented Jul 24, 2019

πŸ“² What

Attempts to fix an escalating crash that we've been seeing in our crash reports which appear to be linked to parsing HTML strings using NSAttributedString.DocumentType.html outside of the main thread. Although I have not been able to reproduce this crash myself, this is my suggested fix which I'd like to ship with the next release to see if it brings the reported crashes down.

πŸ€” Why

This crash has been rising in our crash reports (link below).

πŸ›  How

Ensure that functions in String+SimpleHTML.swift always execute on the main thread.

πŸ‘€ See

https://fabric.io/kickstarter2/ios/apps/com.kickstarter.kickstarter/issues/5c19e0ddf8b88c2963607faa?time=last-seven-days
https://stackoverflow.com/questions/28915954/nsattributedstring-initwithdata-and-nshtmltextdocumenttype-crash-if-not-on-main

βœ… Acceptance criteria

  • No regression or noticeable performance issues introduced by this change.

@justinswart
Copy link
Contributor Author

if Thread.isMainThread {
return parsedHtml()
} else {
return DispatchQueue.main.sync {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be async? πŸ€”

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually do want this to run synchronously on the main thread. The difference between async and sync here is essentially that the code after the closure won't be executed until the closure returns, this is also why we're able to just do return return DispatchQueue.main.sync { ... } as it's synchronously returning a value, async would asynchronously execute the closure and return early.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better way to say it is that it blocks the current thread, we also first check that whether we're on the main thread because it will crash if we try to dispatch it in this way if we're already on that thread.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay gotcha πŸ‘

if Thread.isMainThread {
return parsedHtml()
} else {
return DispatchQueue.main.sync {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, should this be async?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, sync is correct as per other answer.

if Thread.isMainThread {
return parsedHtml()
} else {
return DispatchQueue.main.sync {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay gotcha πŸ‘

@justinswart justinswart merged commit b41d2b8 into master Jul 30, 2019
@justinswart justinswart deleted the html-main-thread-crash-fix branch July 30, 2019 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants