It seems to me that
@convention(block) blocks should be considered at compile-time to conform to
AnyObject. It's already an object pointer at runtime, and casting to
AnyObject preserves the existing pointer (this can be confirmed at the REPL).
The primary use-case for having this be considered to conform to
AnyObject is the ability to use
Unmanaged to explicitly control its lifetime (extremely useful for passing ownership of a block to a queue to ensure it deallocates on that queue). I could just cast it to
AnyObject but then I'd have to do an
as! cast back and I don't like that unsafety. My workaround in PMHTTP uses a wrapper
private class to hold the block, which is doable but annoying and involves otherwise-unnecessary allocation (though in this case the block in question isn't
@convention(block) so this pitch wouldn't actually solve it here, but it would for the work I'm trying to do right now).
There's probably other scenarios where having such a block inherit from
AnyObject would be useful as well, but
Unmanaged is the only one I can think of off the top of my head.
Note that this would only be possible on Darwin platforms.
@convention(block) is not AnyObject-compatible on platforms without ObjC interop.
@convention(block) even do on non-ObjC platforms? Is it just ignored there?
It uses the Clang block ABI, which is platform-independent aside from the ObjC id-compatibility bits. It doesn't show up much outside of Darwin, but does appear in the implementations of corelibs Foundation and Dispatch.
If you have any alternative ideas for solving my "pass ownership of a block to a queue/thread such that I don't release on the current thread after" that I'm trying to use
Unmanaged for, I'm all ears.
The root problem here is the block capturing a thread-confined object, passing through a background thread, then inadvertently deallocating on that background thread, thus releasing (and potentially deallocating) the thread-confined object on the wrong thread.
Personally I'm ok with this only being supported on Darwin, since that's all I care about, but I realize that we're trying to minimize platform behavioral differences.
Yeah, I don't know that platform divergence has to be a showstopper in this case, since I don't think there'd ever be much use of blocks on other platforms to begin with above the corelibs glue layers.