Some classes returned by objc_getClassList aren't accessible

354 Views Asked by At

My code is crashing (rarely) while accessing classes retrieved by objc_getClassList

Crash message:

objc[48740]: Attempt to use unknown class 0x600000ac2640.

var numClasses: Int32 = 0
var newNumClasses = objc_getClassList(nil, 0)
var classes: UnsafeMutablePointer<AnyClass>?

while (numClasses < newNumClasses) { // calling objc_getClassList until all returned classes are fitting into the buffer
    numClasses = newNumClasses
    if let classes = classes {
        classes.deallocate()
    }
    classes = UnsafeMutablePointer<AnyClass>.allocate(capacity: Int(numClasses))
    let buffer = AutoreleasingUnsafeMutablePointer<AnyClass>(classes)
    newNumClasses = objc_getClassList(buffer, numClasses);
}

for i in 0..<Int(newNumClasses) {
    let someclass: AnyClass = classes![i]
    let s = "\(someclass)" // crash happens here
    
    // not very costly computations here
}

Mostly it happens when iteration is performed for 80% or so. Total number of classes is around 50000. It reproduces more often on slower devices/simulators. No other signs of heap corruption are present. Memory graph is fine.

Classes around the broken one looks somewhat like this: fir_420DF5A9-4BF1-468C-8919-FFAA7D864314_GDTCCTUploadOperation (this is a name of the class. Looks firebasy).

EDIT: Alternatively

var count: UInt32 = 0
guard let classList = objc_copyClassList(&count) else {
    return []
}
return UnsafeBufferPointer(start: classList, count: Int(count)).filter { (type: AnyClass) in
    return class_conformsToProtocol(type, protocolName)
}

Produces the same result (again, very rarely)

Please let me know if anyone has an idea how to filter out dead/inaccessible classes.

Thank you.

0

There are 0 best solutions below