struct Container {
let closure: (Int) -> Void
}
let container = Container { param in
print("\(param)")
}
One can assume calling container.closure(42) will print out 42, which is true.
However, if this same closure is retrieved from the container's Mirror:
let mirror = Mirror(reflecting: container)
let closure = mirror.children
.first(where: { $0.label == "closure" })!
.value as! ((Int) -> Void)
... then calling closure(42) distorts the parameter's value, and it prints out 6166589480.
The same thing happens if you use String instead of Int, and I assume with other types too. If I pass a reference to an object, expectedly that reference gets messed up as well and I get EXC_BAD_ACCESS when trying to access the object.
Is this a bug in the Standard Library or am I missing something?
Unfortunately, I don't have access to the Container's sources, which is the main reason I had to appeal to reflection in the first place. Submitted a radar.
I see. If you have a good understanding what Container type has you can create your version of it, typecast and call through your copy without the need of using mirroring API:
struct Container {
let closure: (Int) -> Void
}
var container = Container { param in
print("\(param)")
}
container.closure(42)
struct ContainerCopy {
let closure: (Int) -> Void
}
withUnsafeBytes(of: &container) { p in
let r = p.baseAddress!.assumingMemoryBound(to: ContainerCopy.self).pointee
r.closure(42)
}
print()
Workarounds aside it would be interesting if someone from standard library / compiler team comment on this bug.