My block is not retaining some of its objects
Posted
by
Drew Crawford
on Stack Overflow
See other posts from Stack Overflow
or by Drew Crawford
Published on 2011-01-03T20:14:03Z
Indexed on
2011/01/03
20:54 UTC
Read the original article
Hit count: 495
From the Blocks documentation:
In a reference-counted environment, by default when you reference an Objective-C object within a block, it is retained. This is true even if you simply reference an instance variable of the object.
I am trying to implement a completion handler pattern, where a block is given to an object before the work is performed and the block is executed by the receiver after the work is performed. Since I am being a good memory citizen, the block should own the objects it references in the completion handler and then they will be released when the block goes out of scope. I know enough to know that I must copy
the block to move it to the heap since the block will survive the stack scope in which it was declared.
However, one of my objects is getting deallocated unexpectedly. After some playing around, it appears that certain objects are not retained when the block is copied to the heap, while other objects are. I am not sure what I am doing wrong. Here's the smallest test case I can produce:
typedef void (^ActionBlock)(UIView*);
In the scope of some method:
NSObject *o = [[[NSObject alloc] init] autorelease];
mailViewController = [[[MFMailComposeViewController alloc] init] autorelease];
NSLog(@"o's retain count is %d",[o retainCount]);
NSLog(@"mailViewController's retain count is %d",[mailViewController retainCount]);
ActionBlock myBlock = ^(UIView *view) {
[mailViewController setCcRecipients:[NSArray arrayWithObjects:@"[email protected]",nil]];
[o class];
};
NSLog(@"mailViewController's retain count after the block is %d",[mailViewController retainCount]);
NSLog(@"o's retain count after the block is %d",[o retainCount]);
Block_copy(myBlock);
NSLog(@"o's retain count after the copy is %d",[o retainCount]);
NSLog(@"mailViewController's retain count after the copy is %d",[mailViewController retainCount]);
I expect both objects to be retained by the block at some point, and I certainly expect their retain counts to be identical. Instead, I get this output:
o's retain count is 1
mailViewController's retain count is 1
mailViewController's retain count after the block is 1
o's retain count after the block is 1
o's retain count after the copy is 2
mailViewController's retain count after the copy is 1
o
(subclass of NSObject
) is getting retained properly and will not go out of scope. However mailViewController
is not retained and will be deallocated before the block is run, causing a crash.
© Stack Overflow or respective owner