Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objc_copyClassList: crash EXC_BAD_INSTRUCTION after update to iOS 13.4 / XCode 11.4

after updating to iOS 13.4 / XCode 11.4

this code

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
}

crashes in line let clazz = classList[i] with EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) in Simulator.

this line wasn't in my original code. It is here to show that the subscript crashes and not ClassInfo(...)

Any idea what I can do about it?

(the code is inspired by List all subclasses of one class)

like image 832
Gerd Castan Avatar asked Mar 03 '23 15:03

Gerd Castan


1 Answers

Just noticed: classList is a total misnomer. The returned result has type AutoreleasingUnsafeMutablePointer<AnyClass>?. Convert it to an UnsafeBufferPointer<AnyClass> first, and then do your processing on that:

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 }
}
like image 170
Alexander Avatar answered Mar 05 '23 15:03

Alexander