Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Last active March 8, 2021 18:10
Show Gist options
  • Save JadenGeller/61178fac92ffe595a5a2243e3996400c to your computer and use it in GitHub Desktop.
Save JadenGeller/61178fac92ffe595a5a2243e3996400c to your computer and use it in GitHub Desktop.
Swift Class Reflection Without Valid Instance
/* -fno-objc-arc
CFTypeRef _unsafeCreatePartiallyInitialized(Class c) {
Method method = class_getInstanceMethod([NSObject class], @selector(init));
IMP imp = method_getImplementation(method);
return ((id (*)(id, SEL))imp)([c alloc], @selector(init));
}
void _unsafeDestructPartiallyInitialized(CFTypeRef x) {
Method method = class_getInstanceMethod([NSObject class], @selector(dealloc));
IMP imp = method_getImplementation(method);
((void (*)(id, SEL))imp)(x, @selector(dealloc));
}
*/
import Foundation
class Object: NSObject {
private class func withUnsafePartiallyInitialized<T>(_ block: (Object) throws -> T) rethrows -> T {
func castToInferredType<T, U>(_ x: T) -> U { return x as! U }
let partialObject = _unsafeCreatePartiallyInitialized(self).takeUnretainedValue()
defer { _unsafeDestructPartiallyInitialized(partialObject) }
return try block(unsafeBitCast(partialObject, to: Object.self))
}
class var members: [(name: String, type: Any.Type)] {
return withUnsafePartiallyInitialized { object in
Mirror(reflecting: object).children.map { child in
(child.label!, type(of: child.value))
}
}
}
}
indirect enum MyEnum {
case foo(Int)
case bar(String, MyEnum)
}
class Foo: Object {
var w: MyEnum
var x: String? = "test"
var y: Int
var z: [Object]
init(w: MyEnum, y: Int) {
self.w = w
self.y = y
self.z = []
}
}
print(Foo.members) // -> [("w", ClassReflection.MyEnum), ("x", Swift.Optional<Swift.String>), ("y", Swift.Int), ("z", Swift.Array<reflectiontest.Object>)]
@funnymania
Copy link

can't wait until Im able to understand this 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment