我收到了三个不能重现的类似的崩溃报告(都在iOS 14.4上)。stracktrace会显示如下内容(我只粘贴了应用程序启动的部分):
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001c077d414 __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001de2d8b50 pthread_kill + 272 (pthread.c:1392)
2 libsystem_c.dylib 0x000000019bc5bb74 abort + 104 (abort.c:110)
3 libswiftCore.dylib 0x0000000196795f20 swift::fatalError(unsigned int, char const*, ...) + 60 (Errors.cpp:393)
4 libswiftCore.dylib 0x0000000196796078 swift::swift_abortRetainUnowned(void const*) + 36 (Errors.cpp:460)
5 libswiftCore.dylib 0x00000001967e5844 swift_unknownObjectUnownedLoadStrong + 76 (SwiftObject.mm:895)
6 SwiftUI 0x00000001992b0cdc ViewGraph.graphDelegate.getter + 16 (ViewGraph.swift:234)
7 SwiftUI 0x00000001997e4d58 closure #1 in GraphHost.init(data:) + 80
8 SwiftUI 0x00000001997e6550 partial apply for closure #1 in GraphHost.init(data:) + 40 (<compiler-generated>:0)
9 AttributeGraph 0x00000001bbcc9b88 AG::Graph::Context::call_update() + 76 (ag-closure.h:108)
10 AttributeGraph 0x00000001bbcca1a0 AG::Graph::call_update() + 56 (ag-graph.cc:176)
11 AttributeGraph 0x00000001bbccfd70 AG::Subgraph::update(unsigned int) + 92 (ag-graph.h:709)
12 SwiftUI 0x00000001997e1cdc GraphHost.runTransaction() + 172 (GraphHost.swift:491)
13 SwiftUI 0x00000001997e4e1c GraphHost.runTransaction(_:) + 92 (GraphHost.swift:471)
14 SwiftUI 0x00000001997e37a8 GraphHost.flushTransactions() + 176 (GraphHost.swift:459)
15 SwiftUI 0x00000001997e2c78 specialized GraphHost.asyncTransaction<A>(_:mutation:style:) + 252 (<compiler-generated>:0)
16 SwiftUI 0x00000001993bd2fc AttributeInvalidatingSubscriber.invalidateAttribute() + 236 (AttributeInvalidatingSubscriber.swift:89)
17 SwiftUI 0x00000001993bd1f8 AttributeInvalidatingSubscriber.receive(_:) + 100 (AttributeInvalidatingSubscriber.swift:53)
18 SwiftUI 0x00000001993bd914 protocol witness for Subscriber.receive(_:) in conformance AttributeInvalidatingSubscriber<A> + 24 (<compiler-generated>:0)
19 SwiftUI 0x000000019956ba34 SubscriptionLifetime.Connection.receive(_:) + 100 (SubscriptionLifetime.swift:195)
20 Combine 0x00000001a6e67900 ObservableObjectPublisher.Inner.send() + 136 (ObservableObject.swift:115)
21 Combine 0x00000001a6e670a8 ObservableObjectPublisher.send() + 632 (ObservableObject.swift:153)
22 Combine 0x00000001a6e4ffdc PublishedSubject.send(_:) + 136 (PublishedSubject.swift:82)
23 Combine 0x00000001a6e76994 specialized static Published.subscript.setter + 388 (Published.swift:0)
24 Combine 0x00000001a6e75f74 static Published.subscript.setter + 40 (<compiler-generated>:0)
25 MyApp 0x00000001005d1228 counter.set + 32 (Preferences.swift:0)
26 MyApp 0x00000001005d1228 Preferences.counter.modify + 120 (Preferences.swift:0)
27 MyApp 0x00000001005ca440 MyView.changeCounter(decrease:) + 344 (MyView.swift:367)
28 MyApp 0x00000001005cf110 0x100584000 + 307472
29 MyApp 0x00000001005e65d8 thunk for @escaping @callee_guaranteed () -> () + 20 (<compiler-generated>:0)
30 MyApp 0x00000001005a8828 closure #2 in MySheet.body.getter + 140 (MySheet.swift:0)发生的情况是,我有一个带有按钮的工作表,当单击它时,工作表消失了,并且在onDisappear中,主视图MyView中的changeCounter方法被调用来更改counter。当调用/打开工作表时,方法changeCounter将从MyView传递到工作表。
这是MyView中的.sheet方法
.sheet(item: $activeSheet) { item in
switch item {
case .MY_SHEET:
MySheet(changeCounter: {changeCounter(decrease: true)}, changeTimer, item: $activeSheet)
}
}这是工作表的(重要部分):
struct MySheet: View {
var changeCounter: () -> Void
var changeTimer: () -> Void
@Binding var item: ActiveSheet?
@State var dismissAction: (() -> Void)?
var body: some View {
GeometryReader { metrics in
VStack {
Button(action: {
self.dismissAction = changeCounter
self.item = nil
}, label: {
Text("change_counter")
})
Button(action: {
self.dismissAction = changeTimer
self.item = nil
}, label: {
Text("change_timer")
})
}.frame(width: metrics.size.width, height: metrics.size.height * 0.85)
}.onDisappear(perform: {
if self.dismissAction != nil {
self.dismissAction!()
}
})
}
}下面是包含preferences对象的changeCounter:
struct MyView: View {
@EnvironmentObject var preferences: Preferences
var body: some View {...}
func changeCounter(decrease: Bool) {
if decrease {
preferences.counter -= COUNTER_INTERVAL
}
}
}Preferences是一个带有counter变量的ObservableObject:
class Preferences: ObservableObject {
let userDefaults: UserDefaults
init(_ userDefaults: UserDefaults) {
self.userDefaults = userDefaults
self.counter = 0
}
@Published var counter: Int {
didSet {
self.userDefaults.set(counter, forKey: "counter")
}
}
}它会更改UserDefaults.standard类型的userDefaults中的值。
谁知道这种崩溃是如何发生的,在什么情况下会发生?因为它现在在用户的设备上只发生了三次,我不能重现它。
发布于 2021-06-13 12:52:47
让我们分析一下
Button(action: {
self.dismissAction = changeCounter 1)
self.item = nil 2)
}, label: {第1行)更改内部工作表状态,启动工作表视图的更新。第2行)更改外部状态,启动工作表的关闭(可能还会更新父视图)。
它甚至听起来像是两个冲突的过程(即使没有依赖流,但第二次查看代码取决于第一次的结果)。因此,这是非常危险的逻辑,应该避免。
一般而言,正如我在评论中所写的那样,在一个闭包中更改两个状态总是有风险的,因此我将重写逻辑以获得类似(Sketch)的内容:
Button(action: {
self.result = changeCounter // one external binding !!
}, label: {,即。启动一些外部活动的一个状态变化...
代码的可能解决方法(如果由于任何原因您不能更改逻辑)是在时间上分离这些状态的更改,例如
Button(action: {
self.dismissAction = changeCounter // updates sheet
DispatchQueue.main.async { // or after some min delay
self.item = nil // closes sheet after (!) update
}
}, label: {https://stackoverflow.com/questions/67320117
复制相似问题