in src/BlocksRuntime/runtime.c [672:733]
void _Block_object_assign(void *destAddr, const void *object, const int flags) {
switch (os_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) {
case BLOCK_FIELD_IS_OBJECT:
/*******
id object = ...;
[^{ object; } copy];
********/
_Block_retain_object(object);
_Block_assign((void *)object, destAddr);
break;
case BLOCK_FIELD_IS_BLOCK:
/*******
void (^object)(void) = ...;
[^{ object; } copy];
********/
_Block_assign(_Block_copy_internal(object, false), destAddr);
break;
case BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK:
case BLOCK_FIELD_IS_BYREF:
/*******
// copy the onstack __block container to the heap
__block ... x;
__weak __block ... x;
[^{ x; } copy];
********/
_Block_byref_assign_copy(destAddr, object, flags);
break;
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT:
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK:
/*******
// copy the actual field held in the __block container
__block id object;
__block void (^object)(void);
[^{ object; } copy];
********/
// under manual retain release __block object/block variables are dangling
_Block_assign((void *)object, destAddr);
break;
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK:
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_WEAK:
/*******
// copy the actual field held in the __block container
__weak __block id object;
__weak __block void (^object)(void);
[^{ object; } copy];
********/
_Block_assign_weak(object, destAddr);
break;
default:
break;
}
}