Last active
March 8, 2021 18:10
-
-
Save JadenGeller/61178fac92ffe595a5a2243e3996400c to your computer and use it in GitHub Desktop.
Swift Class Reflection Without Valid Instance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -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>)] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
can't wait until Im able to understand this 😁