Memory management with MABlockClosure under ARC?
tonyxiao opened this issue · 4 comments
What's the right memory management practice with BlockFptr
and BlockFptrAuto
when calling client is using ARC?
In particular, it appears that if look at the example code in the block
int x = 42;
void (*fptr)(void) = BlockFptrAuto(^{ NSLog(@"%d", x); });
fptr(); // prints 42!
It seems that the moment we hit the end of the autorelease pool the fptr
pointer will no longer be valid. So block needs to be explicitly declared and retained somewhere else. Is that the case?
just tested. Empirically the answer is yes, the block does need to be retained somehow. Here's a convenience function to simplify that task.
void *BlockFptrRetain(id block, id owner) {
block = [block copy]; // Make sure block is on the heap first
objc_setAssociatedObject(owner, &block, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return BlockFptr(block);
}
Just confirming, you're correct. As you can see, the implementation in BlockFptr
doesn't retain the block, and there's nothing else going on behind the scenes to make it happen. My intended use case was for immediate callbacks, but if you want something longer term, your solution should work.
Revising my convenience function. it should actually be. Note the removed &
symbol.
void *BlockFptrRetain(id block, id owner) {
block = [block copy]; // Make sure block is on the heap first
objc_setAssociatedObject(owner, block, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return BlockFptr(block);
}