Is it possible to indicate that the argument of a particular method has weak semantics?
This is not what your Objective-C code example does. You accidentally get almost weak semantics, and you have undefined behavior (race condition) that is not found in real weak links.
myMethod can send a message to la-la-land at any point in the sequence (the first NSLog statement or the second, or even in the middle of NSLog somewhere ... even if the ARC does not disappear while maintaining arg0 , you are still chasing the release of the main queue or worse - save the zombie object).
Declaring something as __block means only allocating a slot in the heap environment for the block (since dispatch_async guaranteed to allow the block to escape, it will move from the block allocated by the stack to the heap block and one of the storage slots in this heap block environment will be for your __block variable In ARC, a block will automatically have Block_copy , possibly aptly named Block_copy_to_heap ).
This means that both instances of the block instance will point to the same memory location.
If this helps, imagine this really stupid code that has an obvious race condition. Each of the 1000 blocks queues all attempts to change unsafe . We are almost guaranteed to make unpleasant statements inside the if block, because our purpose and comparison are not atomic, and we fight for the same place in memory.
static volatile size_t unsafe = 0; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_apply(1000, queue, ^(size_t instance) { unsafe = instance; if (unsafe != instance) { FORMAT_ALL_STORAGE(); SEND_RESIGNATION_EMAIL(); WATCH_THE_WORLD_BURN(); } });
Your Swift example does not have the same problem, because a block that does not change the value probably captures (and saves) the object, so it does not see the change from another block.
It is up to the closure creator to deal with the consequences of memory management, so you cannot create an API contract that does not provide for any save cycles in closure other than naming something like @noescape , in which case Swift won't save / release or other memory management, because the block does not survive the current stack stack. This prevents sending an asynchronous message for obvious reasons.
If you want to present an API contract that allows this, you can have a type that accepts the protocol protocol Consumer: class { func consume(thing: Type) } , then weak links to instances of Consumer are stored inside your API.
Another method is to accept the instance version of the instance instance and weak capture of self :
protocol Protocol: class { } typealias FuncType = () -> Void var _responders = [FuncType]() func registerResponder<P: Protocol>(responder: P, usingHandler handler: (P) -> () -> Void) { _responders.append({ [weak responder] in guard let responder = responder else { return } handler(responder)() }) } class Inst: Protocol { func myFunc() { } } let inst = Inst() registerResponder(inst, usingHandler: Inst.myFunc)