-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
withValuePointer() sees object not as a class instance but an existential instance #81
Comments
What's really weird to me is if I break right here on the func withValuePointer<Value, Result>(of value: inout Value, _ body: ...) throws -> Result {
--> let kind = Kind(type: Value.self) // po type(of: value) → SwiftEXTests.SwiftEXTests
let obj = value as AnyObject
let cls: AnyClass = object_getClass(obj)!
let same = cls === cls
switch kind {
case .struct:
return try withUnsafePointer(to: &value) { try body($0.mutable.raw) }
case .class:
return try withClassValuePointer(of: &value, body)
case .existential:
return try withClassValuePointer(of: &value, body)
default:
throw RuntimeError.couldNotGetPointer(type: Value.self, value: value)
}
} (Ignore the code I added for myself for testing) public enum Kind {
...
init(type: Any.Type) {
--> let pointer = metadataPointer(type: type) // po type(of: value) → Any
self.init(flag: pointer.pointee)
}
} |
Update: even if I force it to return |
So As for inheritance, it may be an objc thing but I am not too sure at the moment, Ill keep looking into it though. The I wrote a quick unit test in your project to verify: class Foo {
let a: Int = 1
}
class Bar: Foo {
let b = Baz()
}
class Baz {}
let bar = Bar()
let info = try typeInfo(of: Bar.self)
let aProp = try info.property(named: "a")
let a: Int = try aProp.get(from: bar) as! Int
let bProp = try info.property(named: "b")
let b = try bProp.get(from: bar) as! Baz
XCTAssert(a == 1)
XCTAssert(b === bar.b) |
I think the rules are different across module boundaries or when subclassing an objc class |
Shouldn't |
In a generic context things get a bit tricky, type of
It manually unboxes the value. Its done like this to simplify things. Having it always boxed made it a bit more predicable. Check out the docs on it https://developer.apple.com/documentation/swift/2885064-type . See the "Finding the Dynamic Type in a Generic Context" section. Also here's an interesting example to help illustrate: struct Foo {}
func holdMyBeer<T>(val: T) {
print(T.self)
print(type(of: val))
print(type(of: val as Any))
}
let val = 1
holdMyBeer(val: val) // Int, Int, Int
holdMyBeer(val: val as Any) // Any, Any, Int Sorry didn't mean to close it |
That's crazy. Well then I guess the only problem is the ivar offset thing, which I've been working on. Tell me, is one of the members in |
I'm not sure what's going on, but whatever it is I think I might be doing something wrong.
Here is a project that demonstrates the issue: https://github.com/FLEXTool/SwiftEX
Select the
SwiftEXTests
scheme and run thetestMirror()
test. It fails. My testing shows that for some reason,Value.self
inside the call towithValuePointer()
is seen as an existential instead of a class type. It appears to be correct, too, which tells me I'm the one doing something wrong.The gist of what I'm trying to do is to wrap your APIs and make it work like a readwrite
Mirror
, so that I don't have to fumble with.property(named:)
andproperty.set(value:on:)
orproperty.get(on:)
every time I want to do something.Any help is appreciated!
The text was updated successfully, but these errors were encountered: