NSAttributedString initWithData and NSHTMLTextDocumentType crash if not on main thread

∥☆過路亽.° 提交于 2019-11-27 13:14:36

问题


calling

NSAttributedString * as = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} documentAttributes:nil error:nil];

on other than main thread, results in a crash

1   0x194b861fc <redacted>
2   0x19801d31c <redacted>
3   0x198010eb4 _os_once
4   0x19801aa2c pthread_once
5   0x195a0858c <redacted>
6   0x195a07c78 WebKitInitialize
7   0x18bb38918 <redacted>
8   0x10020cdf0 _dispatch_client_callout
9   0x10020dcfc dispatch_once_f
10  0x1977f8bd0 <redacted>
11  0x1978009ac <redacted>
12  0x19780bdb8 <redacted>
13  0x1940b259c _NSReadAttributedStringFromURLOrData
14  0x1940b0eb4 <redacted>
15  0x1001041a0 -[MPMPostTextBrickCell attributedTextWithHTMLString:]
16  0x100103d3c __39-[MPMPostTextBrickCell setupWithBrick:]_block_invoke
17  0x187fb3508 <redacted>
18  0x187f04c94 <redacted>
19  0x187ef461c <redacted>
20  0x187fb626c <redacted>
21  0x10020cdf0 _dispatch_client_callout
22  0x100217854 _dispatch_queue_drain
23  0x100210120 _dispatch_queue_invoke
24  0x10021975c _dispatch_root_queue_drain
25  0x10021af18 _dispatch_worker_thread3
26  0x1980192e4 _pthread_wqthread
27  0x198018fa8 start_wqthread

when i don't specify the attribute bellow, than it works

NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,

I need to parse the string on background thread, but this makes it impossible :(


回答1:


The documentation is pretty explicit about that.

The HTML importer should not be called from a background thread (that is, the options dictionary includes NSDocumentTypeDocumentAttribute with a value of NSHTMLTextDocumentType). It will try to synchronize with the main thread, fail, and time out. Calling it from the main thread works (but can still time out if the HTML contains references to external resources, which should be avoided at all costs). The HTML import mechanism is meant for implementing something like markdown (that is, text styles, colors, and so on), not for general HTML import.

Using the HTML importer (NSHTMLTextDocumentType) is only possible on the main thread.

(Source: Apple's documentation)




回答2:


Maybe its too late to answer this question, but may help others.

Actually NSAttributedString and NSHTMLTextDocumentType must run asynchronously either on main queue or a global queue.

You can use it in a background thread but you have to dispatch your code block containing NSAttributedString's initializer on a global or main queue. For example:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in




            print("Started on \(NSThread.currentThread())")

            let encodedData = "<font color=\"red\">Hello</font>".dataUsingEncoding(NSUTF8StringEncoding)!
            let attributedOptions : [String: AnyObject] = [
                NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding
            ]


            let attributedString = (try? NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil) ?? NSAttributedString(string: ""))



            print("Finished")

        }


来源:https://stackoverflow.com/questions/28915954/nsattributedstring-initwithdata-and-nshtmltextdocumenttype-crash-if-not-on-main

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!