EXC_BAD_ACCESS KERN_INVALID_ADDRESS 结构 Decodable.init(来自:)
EXC_BAD_ACCESS KERN_INVALID_ADDRESS on Struct Decodable.init(from:)
我有一个功能,最多可以同时 运行 两次从 API 中获取信息。在 Google Crashlytics 中,我看到不少用户受到此崩溃的影响,但我从未见过类似的情况,我不确定从这里该何去何从。
方法的核心:
URLSession.shared.dataTask(with: urlRequest) { (data, res, err) in
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(self.dateFormatter)
let json = try decoder.decode([String: TokenResponse].self, from: data)
}
catch {
print(error.localizedDescription)
}
}.resume()
令牌响应:
struct TokenResponse: Decodable {
var ticket : String
var expiration : Date?
var sessionId: String
}
堆栈跟踪:
Crashed: com.apple.NSURLSession-delegate
0 libicucore.A.dylib 0xe4874 icu::Calendar::clear() + 168
1 CoreFoundation 0x57ab4 __cficu_ucal_clear + 28
2 CoreFoundation 0x57ab4 __cficu_ucal_clear + 28
3 CoreFoundation 0xca884 CFDateFormatterGetAbsoluteTimeFromString + 396
4 CoreFoundation 0xe0490 CFDateFormatterCreateDateFromString + 108
5 Foundation 0x1c2dc getObjectValue + 272
6 Foundation 0x9f300 -[NSDateFormatter getObjectValue:forString:errorDescription:] + 200
7 Foundation 0xbb5d0 -[NSDateFormatter dateFromString:] + 64
8 libswiftFoundation.dylib 0x37a58 __JSONDecoder.unbox(_:as:) + 592
9 libswiftFoundation.dylib 0x21064 __JSONDecoder.unbox_(_:as:) + 452
10 libswiftFoundation.dylib 0x1e040 _JSONKeyedDecodingContainer.decode<A>(_:forKey:) + 848
11 libswiftFoundation.dylib 0x27a48 protocol witness for KeyedDecodingContainerProtocol.decode<A>(_:forKey:) in conformance _JSONKeyedDecodingContainer<A> + 56
12 libswiftFoundation.dylib 0x258e0 protocol witness for KeyedDecodingContainerProtocol.decode<A>(_:forKey:) in conformance _JSONKeyedDecodingContainer<A> + 36
13 libswiftCore.dylib 0x549a8 KeyedDecodingContainerProtocol.decodeIfPresent<A>(_:forKey:) + 648
14 libswiftFoundation.dylib 0x231dc protocol witness for KeyedDecodingContainerProtocol.decodeIfPresent<A>(_:forKey:) in conformance _JSONKeyedDecodingContainer<A> + 36
15 libswiftCore.dylib 0x67dbc _KeyedDecodingContainerBox.decodeIfPresent<A, B>(_:forKey:) + 520
16 libswiftCore.dylib 0x55880 KeyedDecodingContainer.decodeIfPresent<A>(_:forKey:) + 76
17 MyApp 0x1648dc MyClass.TokenResponse.init(from:) + 4344695004 (<compiler-generated>:4344695004)
18 MyApp 0x164a78 protocol witness for Decodable.init(from:) in conformance MyClass.TokenResponse + 4344695416 (<compiler-generated>:4344695416)
19 libswiftCore.dylib 0x34c124 dispatch thunk of Decodable.init(from:) + 32
20 libswiftFoundation.dylib 0x51380 specialized __JSONDecoder.unbox<A>(_:as:) + 2540
21 libswiftFoundation.dylib 0x21048 __JSONDecoder.unbox_(_:as:) + 424
22 libswiftFoundation.dylib 0xcfc4 JSONDecoder.decode<A>(_:from:) + 1548
23 libswiftFoundation.dylib 0x44fc4 dispatch thunk of JSONDecoder.decode<A>(_:from:) + 56
24 MyApp 0x12b84c closure #1 in MyClass.GetAllServerTokens() + 188 (MyClass.swift:188)
25 MyApp 0x12add0 thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () + 4344458704 (<compiler-generated>:4344458704)
26 CFNetwork 0x22b34 CFURLRequestSetMainDocumentURL + 3028
27 CFNetwork 0x33af8 _CFNetworkErrorCopyLocalizedDescriptionWithHostname + 11412
28 libdispatch.dylib 0x2914 _dispatch_call_block_and_release + 32
29 libdispatch.dylib 0x4660 _dispatch_client_callout + 20
30 libdispatch.dylib 0xbde4 _dispatch_lane_serial_drain + 672
31 libdispatch.dylib 0xc98c _dispatch_lane_invoke + 444
32 libdispatch.dylib 0x171a8 _dispatch_workloop_worker_thread + 656
33 libsystem_pthread.dylib 0x10f4 _pthread_wqthread + 288
34 libsystem_pthread.dylib 0xe94 start_wqthread + 8
编辑:获取的 JSON 示例。出于安全考虑,我不能 post。它每 2 小时更改一次,因此我没有导致崩溃的确切副本,但它应该始终遵循此模式。 ticket
和 sessionId
永远不会为空:
{
"1": {
"ticket":"aRandomJSONWebTokenHere",
"expiration":"2022-01-16T10:00:38.2775891Z",
"sessionId":"aUuidHere"
},
"2": {
"ticket":"aRandomJSONWebTokenHere",
"expiration":"2022-01-16T10:00:38.2775891Z",
"sessionId":"aUuidHere"
}...all the way until 60
}
编辑 2:self.dateFormatter
:
let dateFormatter : DateFormatter = {
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return df
}()
self.dateFormatter
未修改。它以相同的方式在其他地方使用,作为 dateDecodingStrategy。也许当多个 URLSession 同时读取 self.dateFormatter
时会发生此崩溃?
Maybe this crash happens when more than one URLSession read self.dateFormatter at the same time?
当然,这是可能的。您的代码肯定是线程不安全的!但是很明显该怎么做;在您的 URLSession.shared.dataTask
完成处理程序中,进入主线程并停留在那里。
URLSession.shared.dataTask(with: urlRequest) { (data, res, err) in
guard let data = data else { return }
DispatchQueue.main.async {
do { // ...
}
catch { // ...
}
}
}.resume()
我有一个功能,最多可以同时 运行 两次从 API 中获取信息。在 Google Crashlytics 中,我看到不少用户受到此崩溃的影响,但我从未见过类似的情况,我不确定从这里该何去何从。
方法的核心:
URLSession.shared.dataTask(with: urlRequest) { (data, res, err) in
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(self.dateFormatter)
let json = try decoder.decode([String: TokenResponse].self, from: data)
}
catch {
print(error.localizedDescription)
}
}.resume()
令牌响应:
struct TokenResponse: Decodable {
var ticket : String
var expiration : Date?
var sessionId: String
}
堆栈跟踪:
Crashed: com.apple.NSURLSession-delegate
0 libicucore.A.dylib 0xe4874 icu::Calendar::clear() + 168
1 CoreFoundation 0x57ab4 __cficu_ucal_clear + 28
2 CoreFoundation 0x57ab4 __cficu_ucal_clear + 28
3 CoreFoundation 0xca884 CFDateFormatterGetAbsoluteTimeFromString + 396
4 CoreFoundation 0xe0490 CFDateFormatterCreateDateFromString + 108
5 Foundation 0x1c2dc getObjectValue + 272
6 Foundation 0x9f300 -[NSDateFormatter getObjectValue:forString:errorDescription:] + 200
7 Foundation 0xbb5d0 -[NSDateFormatter dateFromString:] + 64
8 libswiftFoundation.dylib 0x37a58 __JSONDecoder.unbox(_:as:) + 592
9 libswiftFoundation.dylib 0x21064 __JSONDecoder.unbox_(_:as:) + 452
10 libswiftFoundation.dylib 0x1e040 _JSONKeyedDecodingContainer.decode<A>(_:forKey:) + 848
11 libswiftFoundation.dylib 0x27a48 protocol witness for KeyedDecodingContainerProtocol.decode<A>(_:forKey:) in conformance _JSONKeyedDecodingContainer<A> + 56
12 libswiftFoundation.dylib 0x258e0 protocol witness for KeyedDecodingContainerProtocol.decode<A>(_:forKey:) in conformance _JSONKeyedDecodingContainer<A> + 36
13 libswiftCore.dylib 0x549a8 KeyedDecodingContainerProtocol.decodeIfPresent<A>(_:forKey:) + 648
14 libswiftFoundation.dylib 0x231dc protocol witness for KeyedDecodingContainerProtocol.decodeIfPresent<A>(_:forKey:) in conformance _JSONKeyedDecodingContainer<A> + 36
15 libswiftCore.dylib 0x67dbc _KeyedDecodingContainerBox.decodeIfPresent<A, B>(_:forKey:) + 520
16 libswiftCore.dylib 0x55880 KeyedDecodingContainer.decodeIfPresent<A>(_:forKey:) + 76
17 MyApp 0x1648dc MyClass.TokenResponse.init(from:) + 4344695004 (<compiler-generated>:4344695004)
18 MyApp 0x164a78 protocol witness for Decodable.init(from:) in conformance MyClass.TokenResponse + 4344695416 (<compiler-generated>:4344695416)
19 libswiftCore.dylib 0x34c124 dispatch thunk of Decodable.init(from:) + 32
20 libswiftFoundation.dylib 0x51380 specialized __JSONDecoder.unbox<A>(_:as:) + 2540
21 libswiftFoundation.dylib 0x21048 __JSONDecoder.unbox_(_:as:) + 424
22 libswiftFoundation.dylib 0xcfc4 JSONDecoder.decode<A>(_:from:) + 1548
23 libswiftFoundation.dylib 0x44fc4 dispatch thunk of JSONDecoder.decode<A>(_:from:) + 56
24 MyApp 0x12b84c closure #1 in MyClass.GetAllServerTokens() + 188 (MyClass.swift:188)
25 MyApp 0x12add0 thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () + 4344458704 (<compiler-generated>:4344458704)
26 CFNetwork 0x22b34 CFURLRequestSetMainDocumentURL + 3028
27 CFNetwork 0x33af8 _CFNetworkErrorCopyLocalizedDescriptionWithHostname + 11412
28 libdispatch.dylib 0x2914 _dispatch_call_block_and_release + 32
29 libdispatch.dylib 0x4660 _dispatch_client_callout + 20
30 libdispatch.dylib 0xbde4 _dispatch_lane_serial_drain + 672
31 libdispatch.dylib 0xc98c _dispatch_lane_invoke + 444
32 libdispatch.dylib 0x171a8 _dispatch_workloop_worker_thread + 656
33 libsystem_pthread.dylib 0x10f4 _pthread_wqthread + 288
34 libsystem_pthread.dylib 0xe94 start_wqthread + 8
编辑:获取的 JSON 示例。出于安全考虑,我不能 post。它每 2 小时更改一次,因此我没有导致崩溃的确切副本,但它应该始终遵循此模式。 ticket
和 sessionId
永远不会为空:
{
"1": {
"ticket":"aRandomJSONWebTokenHere",
"expiration":"2022-01-16T10:00:38.2775891Z",
"sessionId":"aUuidHere"
},
"2": {
"ticket":"aRandomJSONWebTokenHere",
"expiration":"2022-01-16T10:00:38.2775891Z",
"sessionId":"aUuidHere"
}...all the way until 60
}
编辑 2:self.dateFormatter
:
let dateFormatter : DateFormatter = {
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return df
}()
self.dateFormatter
未修改。它以相同的方式在其他地方使用,作为 dateDecodingStrategy。也许当多个 URLSession 同时读取 self.dateFormatter
时会发生此崩溃?
Maybe this crash happens when more than one URLSession read self.dateFormatter at the same time?
当然,这是可能的。您的代码肯定是线程不安全的!但是很明显该怎么做;在您的 URLSession.shared.dataTask
完成处理程序中,进入主线程并停留在那里。
URLSession.shared.dataTask(with: urlRequest) { (data, res, err) in
guard let data = data else { return }
DispatchQueue.main.async {
do { // ...
}
catch { // ...
}
}
}.resume()