В нашем приложении произошел сбой, который произошел 231 раз и затронул 185 пользователей. Я не уверен, что файл журнала каким-то образом заполнен или это проблема в теме.
Сбой: com.apple.main-thread EXC_BAD_ACCESS 0x00000001052f77e4 NSClassFromString
Crashed: com.apple.main-thread
0 libdyld.dylib 0x195c656c0 <redacted> + 16
1 libdyld.dylib 0x195c65cd4 <redacted> + 52
2 libdyld.dylib 0x195c65b54 <redacted> + 52
3 libdyld.dylib 0x195c724f8 <redacted> + 132
4 libobjc.A.dylib 0x195ba4c38 getPreoptimizedClass + 148
5 libobjc.A.dylib 0x195b8f8d8 getClassExceptSomeSwift(char const*) + 20
6 libobjc.A.dylib 0x195b90784 look_up_class + 100
7 Foundation 0x196222b00 NSClassFromString + 200
8 Foundation 0x196213264 _decodeObjectBinary + 1708
9 Foundation 0x196212928 _decodeObject + 340
10 Foundation 0x196122050 -[NSKeyedUnarchiver decodeObjectForKey:] + 168
11 Foundation 0x196121eac -[NSKeyedUnarchiver decodeObjectOfClasses:forKey:] + 352
12 Foundation 0x196121b04 -[NSCoder(Exceptions) __tryDecodeObjectForKey:error:decodeBlock:] + 96
13 Foundation 0x196121a7c -[NSCoder decodeTopLevelObjectOfClasses:forKey:error:] + 108
14 Foundation 0x196120d08 +[NSKeyedUnarchiver unarchivedObjectOfClasses:fromData:error:] + 136
15 Foundation 0x196167268 +[NSKeyedUnarchiver unarchivedObjectOfClass:fromData:error:] + 116
16 NetworkExtension 0x1a803f0a4 __64-[NEVPNConnection updateSessionInfoForce:withCompletionHandler:]_block_invoke + 512
17 libsystem_networkextension.dylib 0x19ad05e20 __ne_session_get_info_with_parameters_block_invoke.145 + 32
18 libdispatch.dylib 0x195b2d610 _dispatch_call_block_and_release + 24
19 libdispatch.dylib 0x195b2e184 _dispatch_client_callout + 16
20 libdispatch.dylib 0x195ae01d0 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1044
21 CoreFoundation 0x195dde3c4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
22 CoreFoundation 0x195dd93b8 __CFRunLoopRun + 2004
23 CoreFoundation 0x195dd88bc CFRunLoopRunSpecific + 464
24 GraphicsServices 0x19fc44328 GSEventRunModal + 104
25 UIKitCore 0x199e6e6d4 UIApplicationMain + 1936
26 myapp 0x104ba5da0 main + 19 (Log.swift:19)
27 libdyld.dylib 0x195c63460 <redacted> + 4
com.apple.uikit.eventfetch-thread
0 libsystem_kernel.dylib 0x195c375f4 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x195c36a60 mach_msg + 72
2 CoreFoundation 0x195dde068 __CFRunLoopServiceMachPort + 216
3 CoreFoundation 0x195dd9188 __CFRunLoopRun + 1444
4 CoreFoundation 0x195dd88bc CFRunLoopRunSpecific + 464
5 Foundation 0x196118994 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 228
6 Foundation 0x196118874 -[NSRunLoop(NSRunLoop) runUntilDate:] + 88
7 UIKitCore 0x199f0649c -[UIEventFetcher threadMain] + 152
8 Foundation 0x1962490b0 __NSThread__start__ + 848
9 libsystem_pthread.dylib 0x195b7d1ec _pthread_start + 124
10 libsystem_pthread.dylib 0x195b80aec thread_start + 8
На основе этой трассировки стека это произошло в строке 19 класса Log.swift, что составляет handle.closeFile()
.
class Log: TextOutputStream {
func write(_ string: String) {
let fm = FileManager.default
let log = fm.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("myapp.log")
if let handle = try? FileHandle(forWritingTo: log) {
handle.seekToEndOfFile()
handle.write(string.data(using: .utf8)!)
handle.closeFile()
} else {
try? string.data(using: .utf8)?.write(to: log)
}
}
static var log: Log = Log()
private init() {} // we are sure, nobody else could create it
}
Это происходит потому, что он вызывается, когда не работает в главном потоке? Будет ли это ниже решить это? Поскольку мне нужно точное ведение журнала, возможно, мне следует избегать async
и использовать вместо него sync
?
class Log: TextOutputStream {
func write(_ string: String) {
DispatchQueue.main.sync {
let fm = FileManager.default
let log = fm.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("myapp.log")
if let handle = try? FileHandle(forWritingTo: log) {
handle.seekToEndOfFile()
handle.write(string.data(using: .utf8)!)
handle.closeFile()
} else {
try? string.data(using: .utf8)?.write(to: log)
}
}
}
static var log: Log = Log()
private init() {} // we are sure, nobody else could create it
}