@convention(block) blocks should conform to AnyObject

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.

What does @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.

Terms of Service

Privacy Policy

Cookie Policy