Swift cra sh в swift_getSingletonMetadata, «тип доступа к метаданным» - PullRequest
0 голосов
/ 29 мая 2020

Я получаю какие-то странные логи sh из моего приложения Ma c. Вот сбойный поток:

OS Version:      Mac OS X 10.14.6 (18G103)
Report Version:  104

Exception Type:  SIGSEGV
Exception Codes: SEGV_MAPERR at 0x0
Crashed Thread:  8

Thread 8 Crashed:
0   ???                                  0x0000000000000000 0x0 + 0
1   libswiftCore.dylib                   0x00007fff79a743f3 swift_getSingletonMetadata + 578
2   PowerPhotos                          0x000000010323f30d type metadata accessor for PowerPhotos.IPAssetCollectionUpdate (<compiler-generated>:0)
3   libswiftCore.dylib                   0x00007fff79a8c94c swift::TargetProtocolConformanceDescriptor<swift::InProcess>::getCanonicalTypeMetadata() const + 171
4   libswiftCore.dylib                   0x00007fff79a8da24 swift_conformsToSwiftProtocolImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, llvm::StringRef) + 291
5   libswiftCore.dylib                   0x00007fff79a8d884 swift_conformsToProtocolImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*) + 99
6   PowerPhotos                          0x000000010339e7a9 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*)) + 56
7   libswiftCore.dylib                   0x00007fff79a6215a swift::_conformsToProtocol(swift::OpaqueValue const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptorRef<swift::InProcess>, swift::TargetWitnessTable<swift::InProcess> const**) + 41
8   libswiftCore.dylib                   0x00007fff79a65f97 _conformsToProtocols(swift::OpaqueValue const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::TargetWitnessTable<swift::InProcess> const**) + 230
9   libswiftCore.dylib                   0x00007fff79a65369 _dynamicCastToExistential(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::DynamicCastFlags) + 488
10  libswiftCore.dylib                   0x00007fff79836517 Swift._print_unlocked<A, B where B: Swift.TextOutputStream>(A, inout B) -> () + 550
11  PowerPhotos                          0x00000001031e2483 PowerPhotos.IPArchiveUpdateOperation.(loadFromReplay in _C3BCBD43848FA0F2A85DA8591115A6A7)() -> PowerPhotos.IPArchiveLoadResult (<compiler-generated>:0)
12  PowerPhotos                          0x00000001031e1700 PowerPhotos.IPArchiveUpdateOperation.(loadFromPreferredDatabase in _C3BCBD43848FA0F2A85DA8591115A6A7)() -> (PowerPhotos.IPArchiveLoadResult, Swift.Error?) (IPArchiveUpdateOperation.swift:430)
13  PowerPhotos                          0x00000001031e08fa PowerPhotos.IPArchiveUpdateOperation.perform() throws -> Any (IPArchiveUpdateOperation.swift:218)
14  PowerPhotos                          0x00000001031e179c @objc PowerPhotos.IPArchiveUpdateOperation.perform() throws -> Any (<compiler-generated>:0)
15  BWFoundation                         0x00000001036c8173 -[BWOperation main] (BWOperation.m:124)
16  PowerPhotosKit                       0x0000000103898e71 -[IPOperation main] (IPOperation.m:287)
17  Foundation                           0x00007fff502f5ced -[__NSOperationInternal _start:] + 684
18  Foundation                           0x00007fff5031fca7 __NSOQSchedule_f + 226
19  libdispatch.dylib                    0x00007fff7a0055f8 _dispatch_call_block_and_release + 11
20  libdispatch.dylib                    0x00007fff7a00663d _dispatch_client_callout + 7
21  libdispatch.dylib                    0x00007fff7a008de6 _dispatch_continuation_pop + 413
22  libdispatch.dylib                    0x00007fff7a0084a3 _dispatch_async_redirect_invoke + 702
23  libdispatch.dylib                    0x00007fff7a0143bc _dispatch_root_queue_drain + 323
24  libdispatch.dylib                    0x00007fff7a014b46 _dispatch_worker_thread2 + 89
25  libsystem_pthread.dylib              0x00007fff7a2466b3 _pthread_wqthread + 582
26  libsystem_pthread.dylib              0x00007fff7a2463fd start_wqthread + 12
27  ???                                  0x0000000054485244 0x0 + 0

Кадр 11 - это последний раз, когда мой собственный код видели, эта строка кода выглядит так:

return IPArchiveLoadResult(error: NSError(description: "Replay did not complete \(replayDatabase.replayState.debugDescription)"))

Итак, похоже, что вызов debugDescription - это то, что генерирует оставшуюся часть трассировки стека для создания этой интерполированной строки. В конечном итоге это заканчивается в кадре 3, который ссылается на «средство доступа к метаданным типа для PowerPhotos.IPAssetCollectionUpdate».

Но вот что странно: IPAssetCollectionUpdate не имеет абсолютно ничего общего с кодом, вызывающим этот материал. Он находится в совершенно другой части приложения. Поэтому я думаю, что это в основном случайное совпадение, что это запускает любую загрузку метаданных, которую здесь делает Swift.

Глядя на IPAssetCollectionUpdate, я думаю, что вижу, что, вероятно, его сбивает:

@available(OSX 10.15, *)
struct IPAssetCollectionUpdate {
    let assetCollection: PHAssetCollection
    let diff: CollectionDifference<PHAsset>
}

Обратите внимание, что IPAssetCollectionUpdate помечено как доступное только в macOS 10.15, а все сбои происходят в macOS 10.14. PHAssetCollection и PHAsset существуют в macOS 10.14, но CollectionDifference - нет. Это не проблема для остальной части приложения, поскольку все защищено директивой @available, но кажется, что среда выполнения Swift все еще пытается копаться в этой структуре и генерировать некоторые внутренние метаданные и взрывается, когда не может обработать CollectionDifference. Или что-то в этом роде?

В любом случае, это настройка, поэтому мои вопросы:

  1. Следует ли считать это ошибкой Swift? Похоже, что, если все правильно аннотировано директивами доступности, я смогу отправить это на macOS 10.14 и не иметь ничего плохого sh, поскольку я вообще никогда не использую эту структуру в 10.14.
  2. Независимо от того, чья это вина, могу ли я как-нибудь изменить этот код, чтобы он не взорвался на 10.14? Лучшее, что я могу придумать, - это разбить его на загружаемый пакет в моем приложении и загрузить пакет вручную при запуске на 10.15. Кажется, что для этой глупой проблемы много работы, и я хотел бы знать, есть ли другой более простой способ справиться с этим.

Я компилирую это, используя Xcode 11.5 и Swift 5 .

1 Ответ

0 голосов
/ 29 мая 2020

Хорошо, Stack Overflow был для меня здесь хорошей резиновой уткой, я смог избежать sh, выполнив следующие действия:

struct IPAssetCollectionUpdate {
    let assetCollection: PHAssetCollection
    let typeErasedDiff: Any

    var diff: CollectionDifference<PHAsset> {
        return self.typeErasedDiff as! CollectionDifference<PHAsset>
    }
}

Это ужасно, но работает. Но мой вопрос о том, следует ли считать это ошибкой Swift, и есть ли более санкционированный способ написания такого типа кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...