崩溃:Container.swift 第 299 行 Container.resolve<A, B>(入口:ServiceEntryProtocol,调用者:(B)-> 任何)-> A?
Crash: Container.swift line 299 Container.resolve<A, B> (entry : ServiceEntryProtocol, invoker : (B) -> Any) -> A?
最近我在尝试解析对象时开始崩溃。以下是崩溃日志。我可以在第 299 guard let currentObjectGraph = currentObjectGraph else { fatalError() }
行的 Container.swift 中看到,应用程序未获取 currentObjectGraph 并且它失败了。可能的原因是什么?
在我的项目中,我有一个全局级别的汇编程序,它添加了来自不同框架的所有程序集。但是当我试图解决一个对象时,它会崩溃。这是一个中间问题:-
#15. Crashed: com.apple.NSURLSession-work
0 libswiftCore.dylib 0x109a1b95c specialized _assertionFailure(_:_:file:line:flags:) + 97848
1 Swinject 0x1096d4994 Container.resolve<A, B> (entry : ServiceEntryProtocol, invoker : (B) -> Any) -> A? (Container.swift:299)
2 Swinject 0x1096d2e54 Container._resolve<A, B> (name : String?, option : ServiceKeyOption?, invoker : ((B) -> Any) -> Any) -> A? (Container.swift:192)
3 Swinject 0x1096d582c Container.resolve<A> (A.Type, name : String?) -> A? (Container.swift:281)
4 Swinject 0x1096d5918 ContainerSwinjectResolver (Container.swift)
5 Commons 0x10661e268 specialized static NetworkInterceptor.canInit(with : URLRequest) -> Bool (NetworkInterceptor.swift:67)
6 Commons 0x10661c084 @objc static NetworkInterceptor.canInit(with : URLRequest) -> Bool (NetworkInterceptor.swift)
7 CFNetwork 0x1822ec64c -[__NSURLSessionLocal _protocolClassForRequest:] + 188
8 CFNetwork 0x1822ec7f4 -[__NSURLSessionLocal _request:isCacheEquivalentTo:] + 64
9 CFNetwork 0x1822ec9c8 -[__NSURLSessionLocal _cfurlRequest:isCacheEquivalentTo:] + 172
10 CFNetwork 0x18234fcc8 __CFURLCache::checkMemoryCache(__CFString const*, _CFURLRequest const*, NSURLSession const*) + 188
11 CFNetwork 0x18234bfd0 __CFURLCache::CopyResponseForRequestWithCompletionHandler(_CFURLRequest const*, bool, NSURLSession const*, void (_CFCachedURLResponse const*) block_pointer) + 316
12 CFNetwork 0x1824e4020 CFXURLCache::getResponseForTask(NSURLSessionTask const*, unsigned char, void (_CFCachedURLResponse const*) block_pointer) const + 84
13 CFNetwork 0x18244a578 URLConnectionLoader::_loaderEvent_StartLoad(NSURLSessionTask const*) + 1116
14 CFNetwork 0x18238007c -[__NSCFURLLocalSessionConnection withLoaderOnQueue:] + 72
15 CFNetwork 0x1823806a4 -[__NSCFURLLocalSessionConnection _tick_initialize] + 92
16 CFNetwork 0x18237fc24 __71-[__NSCFURLLocalSessionConnection initWithTask:delegate:delegateQueue:]_block_invoke + 40
17 libdispatch.dylib 0x1816dea54 _dispatch_call_block_and_release + 24
18 libdispatch.dylib 0x1816dea14 _dispatch_client_callout + 16
19 libdispatch.dylib 0x1816e896c _dispatch_queue_serial_drain$VARIANT$mp + 528
20 libdispatch.dylib 0x1816e92fc _dispatch_queue_invoke$VARIANT$mp + 340
21 libdispatch.dylib 0x1816e9d20 _dispatch_root_queue_drain_deferred_wlh$VARIANT$mp + 404
22 libdispatch.dylib 0x1816f203c _dispatch_workloop_worker_thread$VARIANT$mp + 644
23 libsystem_pthread.dylib 0x181986f1c _pthread_wqthread + 932
24 libsystem_pthread.dylib 0x181986b6c start_wqthread + 4
总结我们在 github issue 中收敛的解决方案:
在多线程解析服务时,需要使用synchronized resolver,提供线程安全。 Assembler
还不太支持此功能 (Swijnject#221),但您可以通过
解决此问题
let synchronizedResolver = (assembler.resolver as! Container).synchronized()
并在每次 resolve()
所有线程上的服务时使用 Resolver
的这个实例。
在我的例子中,这是因为 .resolve(service) 代码在主线程以外的其他线程上调用。
将其移至主线程解决了崩溃问题。
最近我在尝试解析对象时开始崩溃。以下是崩溃日志。我可以在第 299 guard let currentObjectGraph = currentObjectGraph else { fatalError() }
行的 Container.swift 中看到,应用程序未获取 currentObjectGraph 并且它失败了。可能的原因是什么?
在我的项目中,我有一个全局级别的汇编程序,它添加了来自不同框架的所有程序集。但是当我试图解决一个对象时,它会崩溃。这是一个中间问题:-
#15. Crashed: com.apple.NSURLSession-work
0 libswiftCore.dylib 0x109a1b95c specialized _assertionFailure(_:_:file:line:flags:) + 97848
1 Swinject 0x1096d4994 Container.resolve<A, B> (entry : ServiceEntryProtocol, invoker : (B) -> Any) -> A? (Container.swift:299)
2 Swinject 0x1096d2e54 Container._resolve<A, B> (name : String?, option : ServiceKeyOption?, invoker : ((B) -> Any) -> Any) -> A? (Container.swift:192)
3 Swinject 0x1096d582c Container.resolve<A> (A.Type, name : String?) -> A? (Container.swift:281)
4 Swinject 0x1096d5918 ContainerSwinjectResolver (Container.swift)
5 Commons 0x10661e268 specialized static NetworkInterceptor.canInit(with : URLRequest) -> Bool (NetworkInterceptor.swift:67)
6 Commons 0x10661c084 @objc static NetworkInterceptor.canInit(with : URLRequest) -> Bool (NetworkInterceptor.swift)
7 CFNetwork 0x1822ec64c -[__NSURLSessionLocal _protocolClassForRequest:] + 188
8 CFNetwork 0x1822ec7f4 -[__NSURLSessionLocal _request:isCacheEquivalentTo:] + 64
9 CFNetwork 0x1822ec9c8 -[__NSURLSessionLocal _cfurlRequest:isCacheEquivalentTo:] + 172
10 CFNetwork 0x18234fcc8 __CFURLCache::checkMemoryCache(__CFString const*, _CFURLRequest const*, NSURLSession const*) + 188
11 CFNetwork 0x18234bfd0 __CFURLCache::CopyResponseForRequestWithCompletionHandler(_CFURLRequest const*, bool, NSURLSession const*, void (_CFCachedURLResponse const*) block_pointer) + 316
12 CFNetwork 0x1824e4020 CFXURLCache::getResponseForTask(NSURLSessionTask const*, unsigned char, void (_CFCachedURLResponse const*) block_pointer) const + 84
13 CFNetwork 0x18244a578 URLConnectionLoader::_loaderEvent_StartLoad(NSURLSessionTask const*) + 1116
14 CFNetwork 0x18238007c -[__NSCFURLLocalSessionConnection withLoaderOnQueue:] + 72
15 CFNetwork 0x1823806a4 -[__NSCFURLLocalSessionConnection _tick_initialize] + 92
16 CFNetwork 0x18237fc24 __71-[__NSCFURLLocalSessionConnection initWithTask:delegate:delegateQueue:]_block_invoke + 40
17 libdispatch.dylib 0x1816dea54 _dispatch_call_block_and_release + 24
18 libdispatch.dylib 0x1816dea14 _dispatch_client_callout + 16
19 libdispatch.dylib 0x1816e896c _dispatch_queue_serial_drain$VARIANT$mp + 528
20 libdispatch.dylib 0x1816e92fc _dispatch_queue_invoke$VARIANT$mp + 340
21 libdispatch.dylib 0x1816e9d20 _dispatch_root_queue_drain_deferred_wlh$VARIANT$mp + 404
22 libdispatch.dylib 0x1816f203c _dispatch_workloop_worker_thread$VARIANT$mp + 644
23 libsystem_pthread.dylib 0x181986f1c _pthread_wqthread + 932
24 libsystem_pthread.dylib 0x181986b6c start_wqthread + 4
总结我们在 github issue 中收敛的解决方案:
在多线程解析服务时,需要使用synchronized resolver,提供线程安全。 Assembler
还不太支持此功能 (Swijnject#221),但您可以通过
let synchronizedResolver = (assembler.resolver as! Container).synchronized()
并在每次 resolve()
所有线程上的服务时使用 Resolver
的这个实例。
在我的例子中,这是因为 .resolve(service) 代码在主线程以外的其他线程上调用。 将其移至主线程解决了崩溃问题。