坠毁:com.apple.NSURLSession-代表 - EXC_BAD_ACCESS

Crashed: com.apple.NSURLSession-delegate - EXC_BAD_ACCESS

我在 Google 的 Crashlytics 中看到许多用户发生此崩溃。我在下面发布了堆栈跟踪,但请记住,这发生在许多其他 URL 请求上。我的 URL 请求函数中的 None 在过去几个月内进行了修改,所以我想知道这是否是新 iOS 版本的 Apple 错误?如果有人可以为我分解堆栈跟踪并解释它是 Apple 错误还是我可以修复的东西,那就太好了。

Crashed: com.apple.NSURLSession-delegate
0  r6stats                        0x100b29750 closure #1 in UbiApi.GetServerToken(account:) + 28 (UbiApi.swift:28)
1  r6stats                        0x100b282a8 thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () + 4343775912 (<compiler-generated>:4343775912)
2  CFNetwork                      0x1919f63dc CFNetServiceBrowserSearchForServices + 79304
3  CFNetwork                      0x191a08768 _CFHTTPMessageSetResponseProxyURL + 9196
4  libdispatch.dylib              0x190fbda84 _dispatch_call_block_and_release + 32
5  libdispatch.dylib              0x190fbf81c _dispatch_client_callout + 20
6  libdispatch.dylib              0x190fc7004 _dispatch_lane_serial_drain + 620
7  libdispatch.dylib              0x190fc7c34 _dispatch_lane_invoke + 456
8  libdispatch.dylib              0x190fd24bc _dispatch_workloop_worker_thread + 764
9  libsystem_pthread.dylib        0x1dcf367a4 _pthread_wqthread + 276
10 libsystem_pthread.dylib        0x1dcf3d74c start_wqthread + 8
func GetServerToken(account: Int) {
    guard let url = URL(string: ApiHeaders.Tokens().url + String(account)) else { print("Invalid URL"); return }
        
    var urlRequest = URLRequest(url: url)
    urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
    urlRequest.httpMethod = "GET"
        
    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(LoginResponse.self, from: data)
                
            let expirationDate : Date = json.expiration!
            let token = "Ubi_v1 t=" + json.ticket!
            let sessionId = json.sessionId
                
            UserDefaults.standard.setValue(expirationDate, forKey: "r6_token_expiration_\(account)")
            UserDefaults.standard.setValue(token, forKey: "r6_token_\(account)")
            UserDefaults.standard.setValue(sessionId, forKey: "r6_token_sessionId_\(account)")
                
            UbiApi.accountsNeeded -= 1 // This is declared on line 28
            self.CheckIfTokensAreDone()
        }
        catch {}
    }.resume()
}

你代码的最后一部分是线程不安全的:

    UserDefaults.standard.setValue(expirationDate, forKey: "r6_token_expiration_\(account)")
    UserDefaults.standard.setValue(token, forKey: "r6_token_\(account)")
    UserDefaults.standard.setValue(sessionId, forKey: "r6_token_sessionId_\(account)")
            
    UbiApi.accountsNeeded -= 1 // This is declared on line 28
    self.CheckIfTokensAreDone()

将其序列化到安全线程:

DispatchQueue.main.async {
    UserDefaults.standard.setValue(expirationDate, forKey: "r6_token_expiration_\(account)")
    UserDefaults.standard.setValue(token, forKey: "r6_token_\(account)")
    UserDefaults.standard.setValue(sessionId, forKey: "r6_token_sessionId_\(account)")
            
    UbiApi.accountsNeeded -= 1 // This is declared on line 28
    self.CheckIfTokensAreDone()
}