7

NSAttributedString initWithData und NSHTMLTextDocumentType Absturz, wenn nicht auf Hauptthread

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

auf andere als Haupt-Thread aufrufen, führt zu einem Absturz

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 

, wenn ich nicht angeben, das Attribut unten, als es funktioniert

Ich muss die Zeichenfolge auf Hintergrund Thread analysieren, aber das macht es unmöglich :(

+0

Was ist die Fehlermeldung? – Larme

+0

die Ausnahme ist EXC BAD ACCESS –

Antwort

14

Die Dokumentation ist ziemlich explizit darüber.

Der HTML-Importeur soll nicht von einem Hintergrund-Thread aufgerufen werden (das heißt, enthält die Optionen Wörterbuch NSDocumentTypeDocumentAttribute mit einem Wert von NSHTMLTextDocumentType). Es wird versuchen, mit dem Haupt-Thread zu synchronisieren, fehlschlagen und Timeout. Der Aufruf aus dem Hauptthread funktioniert (kann aber immer noch aussetzen, wenn der HTML-Code Verweise auf externe Ressourcen enthält, die um jeden Preis vermieden werden sollten). Der HTML-Importmechanismus ist dafür gedacht, etwas wie Markdown (dh Textstile, Farben usw.) zu implementieren, nicht für den allgemeinen HTML-Import.

mit dem HTML-Einführers (NSHTMLTextDocumentType) ist nur auf dem Haupt-Thread.

(Quelle: Apple's documentation)

+0

Das Problem dabei ist, dass es die Benutzeroberfläche hängt (vor allem, wenn es in einer TableView oder beim Drücken eines neuen View-Controller getan wird). Gibt es eine Möglichkeit, den HTML-Code in einem Hintergrund-Thread anders als mit NSAttributedString zu analysieren? –

+0

Nicht ohne Verwendung von Bibliotheken von Drittanbietern, die das tun oder einen Parser selbst codieren könnten. Ab sofort gibt es keine API dafür auf einem Hintergrund-Thread von Apple SDK bereitgestellt afaik – AliSoftware

+0

Ich habe 'DTCoreText' hinzugefügt und verwende jetzt ihre' -initWithHTMLData' Methode von NSAttributedString und es scheint bis jetzt viel besser zu arbeiten. –

1

Vielleicht ist es zu spät, um diese Frage zu beantworten, kann aber andere helfen.

Eigentlich NSAttributedString und NSHTMLTextDocumentType muss asynchron entweder auf Hauptwarteschlange oder eine globale Warteschlange ausgeführt werden.

Sie können es in einem Hintergrundthread verwenden, aber Sie müssen Ihren Codeblock mit NSAttributedString Initialisierer in einer globalen oder Hauptwarteschlange versenden. Zum Beispiel:

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") 

     } 
+0

Wäre cool, wenn das wie beschrieben funktioniert, aber zumindest auf iOS 9.2 Xcode Simulator, und mit 'dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0)', zeigt der Stack-Crawl immer noch 'NSAttributedString', stellt seinen eigenen Semaphor ein und wartet auf den Haupt-Thread um die Konvertierung von HTML durchzuführen. –

+0

Haben Sie es in iOS 8.1 versucht? Absturz in der globalen Warteschlange – Startry

+0

Können Sie mir zeigen, wo ist, sagt, dass diese Funktion asynchron ausgeführt werden muss? Ich würde gerne noch etwas lesen. – AnthonyM

-2
+0

Willkommen bei Stack Overflow. Bitte stellen Sie sicher, dass Ihre Antwort in sich abgeschlossen ist. Externe Links können brechen und Ihre Antwort nutzlos machen. Es ist in Ordnung, einen Link bereitzustellen, aber bitte fügen Sie alle notwendigen Teile in Ihre Antwort ein. – sapanoia

+0

Nein, das ist nicht das Problem –