我正在用Combine和SwiftUI编写一个项目,该项目具有RxSwift,RxCocoa和UIKit的向后兼容性,适用于iOS 12/11。我的项目基于许多协议,关联的类型和泛型。当我在iOS 13上运行项目时,它可以正常运行,但在iOS 12上,应用程序突然崩溃。
我正在尝试对Redux架构进行一些更改。我有减速器,动作(作为枚举),商店和商店提供程序(商店提供程序用于实例化两个商店:rxstore和Combinestore。(我知道这不是最好的方法,但是我想了解为什么会出现此错误发生)。
而且我还有一个所谓的ReduxArchiver
和一个ReduxArchiverElement
。这个(ReduxArchiver
)就像是用来处理和保存redux存储更改的侦听器或委托。 (我也知道这不是最好的解决方案)。当存储具有新状态时,ReduxArchiver
处理更改,根据需要修改数据并决定是否在磁盘上保存状态。存档程序还用于在实例化存储时从磁盘加载应用程序状态。
错误为Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)
,当我实例化ReduxArchiver
类型的对象时出现。发生这种情况是由于ReduxArchiverElement<T: Codable>
数组的实例化(请参见下面的代码或此处的代码:https://github.com/mariusjcb/CrossReduxSOA)
有时显示在控制台中:
libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.
我不知道这是我的错,还是因为项目中过多的关联类型/泛型而导致的快速错误。
我同时将合并和swiftui都链接为弱框架,因此缺少SwiftUI / Combine不会有问题。
而且我的框架和库也以Embed & Sign
的形式嵌入到目标设置中。
实际错误:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)
当我在做po $ arg1时:
// On #0 0x0000000108f6a93f in swift_getWitnessTable (): (lldb) po $arg1 <nil> // On #16 0x0000000108f6b308 in swift_getAssociatedTypeWitness (): (lldb) po $arg1 error: Couldn't materialize: couldn't read the value of register rdi error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
当我检查$ rdi时:
//Xcode: 11.2 (lldb) register read General Purpose Registers: rbx = 0x000000010ff7bdb8 libswiftCore.dylib`InitialAllocationPool + 4304 rbp = 0x00007ffee39a3990 rsp = 0x00007ffee39a3960 r12 = 0x000000010cc69448 Models`protocol requirements base descriptor for Redux.Reducer r13 = 0x00000000000000ff r14 = 0x000000010cc69478 Models`associated type descriptor for StateType r15 = 0x000000010d1ba718 type metadata for Reducers.ExampleReducer rip = 0x000000010fea2308 libswiftCore.dylib`swift_getAssociatedTypeWitness + 152 13 registers were unavailable. //Xcode 11.1 (lldb) register read --all General Purpose Registers: rax = 0x0000000000000000 rbx = 0x0000000105d1db74 Models`protocol conformance descriptor for Models.ExampleModel : Swift.Identifiable in Models + 16 rcx = 0x0000000000000000 rdx = 0x0000000000030000 rdi = 0x0000000000000000 rsi = 0x0000000105d1db78 Models`protocol conformance descriptor for Models.ExampleModel : Swift.Identifiable in Models + 20 rbp = 0x00007ffeea8fa960 rsp = 0x00007ffeea8fa8d0 r8 = 0x0000000000000000 r9 = 0x0000000105d1db50 Models`protocol conformance descriptor for Models.ExampleModel : Swift.Encodable in Models + 20 r10 = 0x0000000108fc10a4 libswiftCore.dylib`method descriptor for Swift.Encodable.encode(to: Swift.Encoder) throws -> () r11 = 0x0000000000000001 r12 = 0x0000000105d9c3b0 Models`__unnamed_24 r13 = 0x0000000000000000 r14 = 0x0000000105d1db74 Models`protocol conformance descriptor for Models.ExampleModel : Swift.Identifiable in Models + 16 r15 = 0x0000000105d1db64 Models`protocol conformance descriptor for Models.ExampleModel : Swift.Identifiable in Models rip = 0x0000000108f6a93f libswiftCore.dylib`swift_getWitnessTable + 447 rflags = 0x0000000000000247 cs = 0x000000000000002b fs = 0x0000000000000000
对象的实例:
// In AppDelegate (as property): // ... let state = ExampleStoreBuilder.build() // The Build Method from ExampleStoreBuilder let archiveListeners = [GenericReduxArchiverLogger("example_archiver")] var listeners: [ReduceStoreOutputDelegate] = [GenericReduxStoreLogger("example_logger")] ERROR>> let defaultStoreArchiver = ExampleArchiver<ExampleRxStore>(outputDelegates: archiveListeners) <<<< Error: EXC_BAD_ACCESS listeners.append(defaultStoreArchiver) listeners.append(contentsOf: archiveListeners) if #available(iOS 13.0, *) { listeners.append(ExampleArchiver<ExampleCombineStore>(outputDelegates: archiveListeners)) } let reducer = ExampleReduceBuilder.build() let initialState = defaultStoreArchiver.statesHistory.last?.state ?? .emptyState return ReduxState<ExampleStoreProvider<ExampleReducer>>(initialState, reducedBy: reducer, outputDelegates: listeners)
let defaultStoreArchiver中的EXC_BAD_ACCESS位于ExampleArchiver中的行上:
public var statesHistory = [ReduxArchiveElement<StoreType.ReducerType.StateType>]()
ReduxArchiverElement定义为:
public struct ReduxArchiveElement<T: Codable>: Codable { public let date: Date public let state: T public init(date: Date, state: T) { self.date = date self.state = state } }
最后将StoreType和Reducer定义为:
// ReduceStoreInitializable protocol public protocol ReduceStoreInitializable { associatedtype ReducerType: Reducer ... // Store: public protocol ReduceStore: class, ReduceStoreInitializable { var reducer: ReducerType! { get set } ... // Reducer: public protocol Reducer: class { associatedtype ActionType associatedtype ItemType: Codable associatedtype StateType: Codable associatedtype ErrorType: Error
关于实际错误,堆栈看起来像:
Thread 1 Queue : com.apple.main-thread (serial) * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10) frame #0: 0x00000001063746e4 libswiftCore.dylib`swift_getWitnessTable + 392 frame #1: 0x0000000105802e38 Models`lazy protocol witness table accessor for type ExampleModel and conformance ExampleModel at <compiler-generated>:0 frame #2: 0x0000000105802cf4 Models`instantiation function for generic protocol witness table for ExampleModel at <compiler-generated>:0 frame #3: 0x0000000106374c08 libswiftCore.dylib`swift_getWitnessTable + 1708 frame #4: 0x0000000106385ee8 libswiftCore.dylib`swift::TargetProtocolConformanceDescriptor<swift::InProcess>::getWitnessTable(swift::TargetMetadata<swift::InProcess> const*) const + 496 frame #5: 0x0000000105112fd8 ExampleApp-SwiftUI`swift::swift50override_conformsToProtocol(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, swift::TargetWitnessTable<swift::InProcess> const* (*)(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*)) + 60 frame #6: 0x00000001063607fc libswiftCore.dylib`swift::_conformsToProtocol(swift::OpaqueValue const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptorRef<swift::InProcess>, swift::TargetWitnessTable<swift::InProcess> const**) + 44 frame #7: 0x00000001063863b0 libswiftCore.dylib`swift::_checkGenericRequirements(llvm::ArrayRef<swift::TargetGenericRequirementDescriptor<swift::InProcess> >, std::__1::vector<void const*, std::__1::allocator<void const*> >&, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 1160 frame #8: 0x0000000106383410 libswiftCore.dylib`(anonymous namespace)::DecodedMetadataBuilder::createBoundGenericType(swift::TargetContextDescriptor<swift::InProcess> const*, llvm::ArrayRef<swift::TargetMetadata<swift::InProcess> const*>, swift::TargetMetadata<swift::InProcess> const*) const + 576 frame #9: 0x0000000106382ac4 libswiftCore.dylib`swift::Demangle::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::Node* const&) + 2832 frame #10: 0x0000000106382100 libswiftCore.dylib`swift::Demangle::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::Node* const&) + 332 frame #11: 0x00000001063819e8 libswiftCore.dylib`swift_getTypeByMangledNodeImpl(swift::MetadataRequest, swift::Demangle::Demangler&, swift::Demangle::Node*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 460 frame #12: 0x00000001063817a8 libswiftCore.dylib`swift::swift_getTypeByMangledNode(swift::MetadataRequest, swift::Demangle::Demangler&, swift::Demangle::Node*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 520 frame #13: 0x0000000106381d18 libswiftCore.dylib`swift_getTypeByMangledNameImpl(swift::MetadataRequest, llvm::StringRef, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 648 frame #14: 0x0000000106380110 libswiftCore.dylib`swift::swift_getTypeByMangledName(swift::MetadataRequest, llvm::StringRef, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 520 frame #15: 0x0000000106376a6c libswiftCore.dylib`swift_getAssociatedTypeWitnessSlowImpl(swift::MetadataRequest, swift::TargetWitnessTable<swift::InProcess>*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*) + 492 frame #16: 0x0000000106375018 libswiftCore.dylib`swift_getAssociatedTypeWitness + 176 frame #17: 0x00000001056df53c Stores`ExampleArchiver.init(storeLocation=nil, outputDelegates=1 value, self=0x00000001c0463840) at ExampleArchiver.swift:18:85 frame #18: 0x00000001056df38c Stores`ExampleArchiver.__allocating_init(storeLocation:outputDelegates:) at ExampleArchiver.swift:0 frame #19: 0x00000001056ebc48 Stores`static ExampleStoreBuilder.build(self=Stores.ExampleStoreBuilder) at ExampleStoreBuilder.swift:23:64 frame #20: 0x0000000105000d20 ExampleApp-SwiftUI`AppDelegate.init() at AppDelegate.swift:17:36 frame #21: 0x0000000105000e28 ExampleApp-SwiftUI`@objc AppDelegate.init() at <compiler-generated>:0 frame #22: 0x000000018e4a8a00 UIKit`_UIApplicationMainPreparations + 1688 frame #23: 0x000000018e39d724 UIKit`UIApplicationMain + 184 frame #24: 0x0000000105001404 ExampleApp-SwiftUI`main at AppDelegate.swift:14:7 * frame #25: 0x0000000183e11fc0 libdyld.dylib`start + 4
对于swift_getAssociatedTypeWitness()中的#16 0x0000000106375018,实际的程序集看起来像:
libswiftCore.dylib`swift_getAssociatedTypeWitness: 0x106374f68 <+0>: stp x24, x23, [sp, #-0x40]! 0x106374f6c <+4>: stp x22, x21, [sp, #0x10] 0x106374f70 <+8>: stp x20, x19, [sp, #0x20] 0x106374f74 <+12>: stp x29, x30, [sp, #0x30] 0x106374f78 <+16>: add x29, sp, #0x30 ; =0x30 0x106374f7c <+20>: mov x23, x0 0x106374f80 <+24>: sub x8, x4, x3 0x106374f84 <+28>: lsr x8, x8, #3 0x106374f88 <+32>: ldr x0, [x1, w8, uxtw #3] 0x106374f8c <+36>: tbnz w0, #0x0, 0x106374fa8 ; <+64> 0x106374f90 <+40>: mov x1, #0x0 0x106374f94 <+44>: ldp x29, x30, [sp, #0x30] 0x106374f98 <+48>: ldp x20, x19, [sp, #0x20] 0x106374f9c <+52>: ldp x22, x21, [sp, #0x10] 0x106374fa0 <+56>: ldp x24, x23, [sp], #0x40 0x106374fa4 <+60>: ret 0x106374fa8 <+64>: mov x19, x4 0x106374fac <+68>: mov x20, x3 0x106374fb0 <+72>: mov x21, x2 0x106374fb4 <+76>: mov x22, x1 0x106374fb8 <+80>: adr x0, #0xcd130 ; swift_getAssociatedTypeWitnessSlow::Predicate 0x106374fbc <+84>: nop 0x106374fc0 <+88>: adr x1, #0x3690 ; swift_getAssociatedTypeWitnessSlow::$_8::__invoke(void*) 0x106374fc4 <+92>: nop 0x106374fc8 <+96>: mov x2, #0x0 0x106374fcc <+100>: bl 0x106385ad4 ; swift_once 0x106374fd0 <+104>: nop 0x106374fd4 <+108>: ldr x8, #0xcd10c ; swift_getAssociatedTypeWitnessSlow::Override 0x106374fd8 <+112>: cbz x8, 0x106375000 ; <+152> 0x106374fdc <+116>: adr x5, #0x18a4 ; swift_getAssociatedTypeWitnessSlowImpl(swift::MetadataRequest, swift::TargetWitnessTable<swift::InProcess>*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*) 0x106374fe0 <+120>: nop 0x106374fe4 <+124>: mov x0, x23 0x106374fe8 <+128>: mov x1, x22 0x106374fec <+132>: mov x2, x21 0x106374ff0 <+136>: mov x3, x20 0x106374ff4 <+140>: mov x4, x19 0x106374ff8 <+144>: blr x8 0x106374ffc <+148>: b 0x106374f94 ; <+44> 0x106375000 <+152>: mov x0, x23 0x106375004 <+156>: mov x1, x22 0x106375008 <+160>: mov x2, x21 0x10637500c <+164>: mov x3, x20 0x106375010 <+168>: mov x4, x19 0x106375014 <+172>: bl 0x106376880 ; swift_getAssociatedTypeWitnessSlowImpl(swift::MetadataRequest, swift::TargetWitnessTable<swift::InProcess>*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*) -> 0x106375018 <+176>: b 0x106374f94 ; <+44> <<< Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)
同样对于swift_getWitnessTable()中的#0 0x00000001063746e4,asm看起来也像这样:
0x106374660 <+260>: adr x26, #0xb57a0 ; AllocationPool
0x106374664 <+264>: nop
0x106374668 <+268>: str x21, [sp, #0x30]
0x10637466c <+272>: ldar x24, [x28]
0x106374670 <+276>: cbnz x24, 0x1063747c8 ; <+620>
0x106374674 <+280>: b 0x106374688 ; <+300>
0x106374678 <+284>: add x8, x24, #0x8 ; =0x8
0x10637467c <+288>: csel x28, x24, x8, lo
0x106374680 <+292>: ldar x24, [x28]
0x106374684 <+296>: cbnz x24, 0x1063747c8 ; <+620>
0x106374688 <+300>: cbnz x23, 0x1063747b0 ; <+596>
0x10637468c <+304>: ldrsw x9, [x20]
0x106374690 <+308>: cbz w9, 0x1063746a8 ; <+332>
0x106374694 <+312>: and x8, x9, #0xfffffffffffffffe
0x106374698 <+316>: add x8, x8, x20
0x10637469c <+320>: tbz w9, #0x0, 0x1063746ac ; <+336>
0x1063746a0 <+324>: ldr x8, [x8]
0x1063746a4 <+328>: b 0x1063746ac ; <+336>
0x1063746a8 <+332>: mov x8, #0x0
0x1063746ac <+336>: ldr w12, [x20, #0xc]
0x1063746b0 <+340>: ubfx x9, x12, #6, #1
0x1063746b4 <+344>: add x10, x21, x9, lsl #2
0x1063746b8 <+348>: ubfx x11, x12, #8, #8
0x1063746bc <+352>: madd x9, x11, x14, x10
0x1063746c0 <+356>: ubfx x13, x12, #16, #1
0x1063746c4 <+360>: add x9, x9, x13, lsl #2
0x1063746c8 <+364>: tbnz w12, #0x10, 0x1063746d4 ; <+376>
0x1063746cc <+368>: mov x10, #0x0
0x1063746d0 <+372>: b 0x1063746dc ; <+384>
0x1063746d4 <+376>: mul x11, x11, x14
0x1063746d8 <+380>: ldr w10, [x10, x11]
0x1063746dc <+384>: add x9, x9, x10, lsl #3
0x1063746e0 <+388>: ldrh w9, [x9, #0x2]
-> 0x1063746e4 <+392>: ldr w8, [x8, #0x10] <<< ERROR; I don't understand this line... :(
我正在用Combine和SwiftUI编写一个项目,该项目具有RxSwift,RxCocoa和UIKit的向后兼容性,适用于iOS 12/11。我的项目基于许多协议,关联的类型和泛型。当我...
我不完全理解问题的根本原因,但是我能够通过删除其中一项协议的Identifiable
一致性来解决此问题。我的部署目标是iOS 10,因此事后看来,我不确定为什么我的框架能够在没有@available检查的情况下进行编译。