objc_copyClassList: cra sh EXC_BAD_INSTRUCTION после обновления до iOS 13.4 / XCode 11.4 - PullRequest
2 голосов
/ 25 марта 2020

после обновления до iOS 13.4 / XCode 11.4

этот код

func getSubclassInfos() -> [ClassInfo] {
    let superObject = CityModel.self
    let superClassInfo = ClassInfo(superObject)

    var subclassList = [ClassInfo]()
    var count = UInt32(0)
    guard let classList = objc_copyClassList(&count) else {
        return subclassList
    }
    for i in 0..<Int(count) {
        let clazz = classList[i] // Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
        if let classInfo = ClassInfo(classList[i]),
            let superclassInfo = classInfo.superclassInfo,
            superclassInfo == superClassInfo
        {
            subclassList.append(classInfo)
        }
    }

    return subclassList
}

вылетает в строке let clazz = classList[i] с EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) в симуляторе.

this линии не было в моем исходном коде. Это здесь, чтобы показать, что индекс не работает, а не ClassInfo(...)

Любая идея, что я могу с этим поделать?

(код вдохновлен Список всех подклассов одного класса )

1 Ответ

4 голосов
/ 25 марта 2020

Только что заметил: classList - это неправильное число. Возвращаемый результат имеет тип AutoreleasingUnsafeMutablePointer<AnyClass>?. Сначала преобразуйте его в UnsafeBufferPointer<AnyClass>, а затем выполните следующую обработку:

func getSubclassInfos() -> [ClassInfo] {
    let superObject = CityModel.self
    let superClassInfo = ClassInfo(superObject)

    var count = UInt32(0)
    guard let classListPointer = objc_copyClassList(&count) else { return [] }

    return UnsafeBufferPointer(start: classListPointer, count: Int(count))
        .map(ClassInfo.init)
        .filter { $0 == superClassInfo }
}
...