当我使用 解码 html entites 时出现错误NSAttributedString。我使用 Swift 5。我只想将 html 字符串化。我不想要网络视图。
SwiftUI 文本
Text("It's a party!".decoded)
Run Code Online (Sandbox Code Playgroud)
字符串扩展
extension String {
var decoded: String {
let attr = try? NSAttributedString(data: Data(utf8), options: [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
], documentAttributes: nil)
return attr?.string ?? self
}
}
Run Code Online (Sandbox Code Playgroud)
错误日志
== AttributeGraph: cycle detected through attribute 123464 ===
=== AttributeGraph: cycle detected through attribute 143224 ===
=== AttributeGraph: cycle detected through attribute 128744 ===
Simultaneous accesses to 0x7ff43ff29b50, but modification requires exclusive access.
Previous access (a modification) started at SwiftUI`LayoutComputer.EngineDelegate.spacing() + 44 (0x7fff566b85dc).
Current access (a modification) started at:
0 libswiftCore.dylib 0x00007fff2f41fe90 swift_beginAccess + 568
1 SwiftUI 0x00007fff566b85b0 LayoutComputer.EngineDelegate.spacing() + 44
2 SwiftUI 0x00007fff56657140 accumulateSpacing #1 (ofChild:) in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:resizeChildrenWithTrailingOverflow:) + 289
3 SwiftUI 0x00007fff56656bf0 StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:resizeChildrenWithTrailingOverflow:) + 414
4 SwiftUI 0x00007fff561d9d00 specialized ManagedBufferPointer.init(bufferClass:minimumCapacity:makingHeaderWith:) + 296
5 SwiftUI 0x00007fff561da140 specialized closure #2 in HVStack.updateLayoutComputer<A>(rule:layoutContext:children:) + 142
6 SwiftUI 0x00007fff5626cce0 specialized closure #2 in HVStack.updateLayoutComputer<A>(rule:layoutContext:children:) + 41
7 SwiftUI 0x00007fff56278590 partial apply for specialized closure #2 in HVStack.updateLayoutComputer<A>(rule:layoutContext:children:) + 43
8 SwiftUI 0x00007fff561da3e0 specialized static LayoutComputerDelegate.update<A>(_:maybeInPlace:create:) + 136
9 SwiftUI 0x00007fff56139060 specialized StatefulRule<>.updateLayoutComputer<A>(layout:environment:layoutComputers:) + 176
10 SwiftUI 0x00007fff562692a0 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 236
11 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
12 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
13 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
14 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
15 SwiftUI 0x00007fff56030ec0 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32
16 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
17 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
18 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
19 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
20 SwiftUI 0x00007fff56438660 DynamicLayoutViewChildGeometry.childGeometries.getter + 53
21 SwiftUI 0x00007fff56438740 DynamicLayoutViewChildGeometry.updateValue() + 201
22 SwiftUI 0x00007fff5626e730 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 15
23 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
24 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
25 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
26 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
27 SwiftUI 0x00007fff55f66120 specialized UnaryChildGeometry.parentSize.getter + 28
28 SwiftUI 0x00007fff55f66920 specialized UnaryChildGeometry.value.getter + 91
29 SwiftUI 0x00007fff56035830 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 28
30 SwiftUI 0x00007fff5605a690 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 20
31 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
32 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
33 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
34 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
35 SwiftUI 0x00007fff55f66120 specialized UnaryChildGeometry.parentSize.getter + 28
36 SwiftUI 0x00007fff55f666b0 specialized UnaryChildGeometry.value.getter + 91
37 SwiftUI 0x00007fff56035830 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 28
38 SwiftUI 0x00007fff56040ed0 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 20
39 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
40 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
41 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
42 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
43 SwiftUI 0x00007fff55f66120 specialized UnaryChildGeometry.parentSize.getter + 28
44 SwiftUI 0x00007fff55f666b0 specialized UnaryChildGeometry.value.getter + 91
45 SwiftUI 0x00007fff56035830 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 28
46 SwiftUI 0x00007fff56040ed0 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 20
47 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
48 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
49 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
50 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
51 SwiftUI 0x00007fff55f66120 specialized UnaryChildGeometry.parentSize.getter + 28
52 SwiftUI 0x00007fff55f66440 specialized UnaryChildGeometry.value.getter + 91
53 SwiftUI 0x00007fff56035830 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 28
54 SwiftUI 0x00007fff5604f800 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 20
55 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
56 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
57 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
58 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
59 SwiftUI 0x00007fff55f66120 specialized UnaryChildGeometry.parentSize.getter + 28
60 SwiftUI 0x00007fff55f666b0 specialized UnaryChildGeometry.value.getter + 91
61 SwiftUI 0x00007fff56035830 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 28
62 SwiftUI 0x00007fff56040ed0 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 20
63 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
64 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
65 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
66 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
67 SwiftUI 0x00007fff56030ec0 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 55
68 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
69 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
70 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
71 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
72 SwiftUI 0x00007fff56438660 DynamicLayoutViewChildGeometry.childGeometries.getter + 53
73 SwiftUI 0x00007fff56438740 DynamicLayoutViewChildGeometry.updateValue() + 201
74 SwiftUI 0x00007fff5626e730 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 15
75 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
76 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
77 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
78 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
79 SwiftUI 0x00007fff56030ec0 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 55
80 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
81 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
82 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
83 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
84 SwiftUI 0x00007fff56033ef0 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 63
85 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
86 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
87 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
88 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
89 SwiftUI 0x00007fff568536f0 StyledTextChildGeometry.parentSize.getter + 27
90 SwiftUI 0x00007fff560324b0 specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 41
91 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
92 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
93 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
94 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
95 SwiftUI 0x00007fff5608cb10 LayoutPositionQuery.localPosition.getter + 22
96 SwiftUI 0x00007fff5608cbd0 LayoutPositionQuery.updateValue() + 32
97 SwiftUI 0x00007fff5628dab0 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 15
98 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
99 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
100 AttributeGraph 0x00007fff4be8e654 AG::Graph::input_value_ref_slow(AG::data::ptr<AG::Node>, AG::AttributeID, unsigned int, AGSwiftMetadata const*, bool*, long) + 523
101 AttributeGraph 0x00007fff4be9fcfa AGGraphGetValue + 203
102 SwiftUI 0x00007fff568cd9e0 AnimatableFrameAttribute.updateValue() + 45
103 SwiftUI 0x00007fff5628e5c0 partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 15
104 AttributeGraph 0x00007fff4be8952a AG::Graph::UpdateStack::update() + 505
105 AttributeGraph 0x00007fff4be89a6a AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 335
106 AttributeGraph 0x00007fff4be91884 AG::Subgraph::update(unsigned int) + 781
107 SwiftUI 0x00007fff5693a5f0 GraphHost.runTransaction() + 186
108 SwiftUI 0x00007fff5640e3c0 ViewGraph.updateOutputs(at:) + 90
109 SwiftUI 0x00007fff5689a880 closure #1 in ViewRendererHost.render(interval:updateDisplayList:) + 1305
110 SwiftUI 0x00007fff5688dc20 ViewRendererHost.render(interval:updateDisplayList:) + 340
111 SwiftUI 0x00007fff56a0a640 _UIHostingView.layoutSubviews() + 241
112 SwiftUI 0x00007fff56a0a740 @objc _UIHostingView.layoutSubviews() + 21
113 UIKitCore 0x00007fff24bd69a0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2924
114 QuartzCore 0x00007fff27a7708d -[CALayer layoutSublayers] + 258
115 QuartzCore 0x00007fff27a7d402 CA::Layer::layout_if_needed(CA::Transaction*) + 575
116 QuartzCore 0x00007fff27a89358 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 65
117 QuartzCore 0x00007fff279c8f24 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 496
118 QuartzCore 0x00007fff279ffba0 CA::Transaction::commit() + 783
119 QuartzCore 0x00007fff27a0101c CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 79
120 CoreFoundation 0x00007fff2038b1d1 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
121 CoreFoundation 0x00007fff20385844 __CFRunLoopDoObservers + 547
122 CoreFoundation 0x00007fff2038548f CFRunLoopRunSpecific + 691
123 UIFoundation 0x00007fff23a483bd -[NSHTMLReader _loadUsingWebKit] + 1847
124 UIFoundation 0x00007fff23a49a13 -[NSHTMLReader attributedString] + 22
125 UIFoundation 0x00007fff239c835a _NSReadAttributedStringFromURLOrData + 9439
126 UIFoundation 0x00007fff239c8255 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 144
(lldb)
Run Code Online (Sandbox Code Playgroud)
NSAttributedString 在解析 HTML 时处理运行循环。您可以在对 的调用内对 CFRUnLoopRunSpecific 的调用中看到它initWithData:。这是 NSAttributedString 的一个非常老的问题。(我想我第一次遇到它是在 OS X 10.5 左右,但我确信它比那更旧。)
因为它处理运行循环,所以在评估 HTML 字符串的过程中可能会发生各种情况。定时器可以触发。可以调用延迟选择器。在 SwiftUI 中,这意味着 UI 可能会尝试更新。一团糟。它会在表面上安全的代码中生成竞争条件。实际上你有点幸运,Swift 发现了这种问题并崩溃了。其他常见症状甚至更难调试(由于代码重入而导致的“不可能”死锁是我遇到的最常见的情况)。
简而言之,使用 NSAttributedString 同步评估 HTML 是不安全的。文档不会警告您这一点,并且方法的名称也没有给出任何提示。但你不能。有些人会告诉您确保在主线程上对其进行评估,但即使这样也不能保证如果您在运行循环上还有其他待处理的事情,就不会出现真正奇怪的重入错误。
您需要以另一种方式评估该字符串。例如,请参阅Martin R对如何在 Swift 中解码 HTML 实体?
有关在主线程上运行它如何给您带来麻烦的快速示例,请考虑以下代码:
func delayed() {
print("Should be last")
}
func dothing() {
// Run this on the next runloop
DispatchQueue.main.async { self.delayed() }
// These should print in order
print("Prints first")
print("It's a party!".decoded)
}
// somewhere on the main queue. There's no background threads needed
dothing()
Run Code Online (Sandbox Code Playgroud)
这输出:
Prints first
2020-12-20 22:16:07.976101-0500 test[84698:5693517] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600000bb8520> F8BB1C28-BAE8-11D6-9C31-00039315CD46
Should be last
It's a party!
Run Code Online (Sandbox Code Playgroud)
如果delayed改变任何状态,那么即使一切都在主线程上,事情也可能会在你的控制下发生变化。
(出现奇怪的错误是因为我在 中对此进行了测试didFinishLaunching,这意味着运行循环在应用程序完成启动之前得到处理。这正是您遇到的错误。)
| 归档时间: |
|
| 查看次数: |
1080 次 |
| 最近记录: |