I face a very strange crash on Swift.
Xcode 11.3.1
Swift 5
Case 1
class TestObject {
var deinitExecution: (() -> Void)?
deinit {
// comment this to avoid crash
deinitExecution?()
}
}
private var associatedDynamicTagHandle: UInt8 = 0
class InterestTests: XCTestCase {
func testExample() {
guard let dynamicClass = objc_allocateClassPair(TestObject.self, "DynamicClass", 0) else {
XCTFail()
return
}
objc_registerClassPair(dynamicClass)
objc_setAssociatedObject(dynamicClass, &associatedDynamicTagHandle, true, .OBJC_ASSOCIATION_ASSIGN)
}
}
If I removed code deinitExecution?() or objc_setAssociatedObject(dynamicClass, &associatedDynamicTagHandle, true, .OBJC_ASSOCIATION_ASSIGN). It works fine.
Case 2
class TestObject {
}
private var associatedDynamicTagHandle: UInt8 = 0
class InterestTests: XCTestCase {
func testExample() {
guard let dynamicClass = objc_allocateClassPair(TestObject.self, "DynamicClass", 0) else {
XCTFail()
return
}
objc_registerClassPair(dynamicClass)
objc_setAssociatedObject(dynamicClass, &associatedDynamicTagHandle, true, .OBJC_ASSOCIATION_ASSIGN)
let method = class_getInstanceMethod(dynamicClass, NSSelectorFromString("aName"))
print("method: \(String(describing: method))")
}
}
If I removed code objc_setAssociatedObject(dynamicClass, &associatedDynamicTagHandle, true, .OBJC_ASSOCIATION_ASSIGN). It works fine.
Is this a swift bug?


I think you mis-use
objc_setAssociatedObject. The documentation says:The key point here is that you need an object, not a class.
The runtime functions
objc_allocateClassPairandobjc_registerClassPairjust create new runtime classes, not objects. To get an object, you could useNSClassFromString, callinit()and then associate the tag with it.A complete running example could be (just a console program, no unit test):
with the following output: