从块文档:
在引用计数环境中,默认情况下,当您在块中引用 Objective-C 对象时,它会被保留。即使您只是引用对象的实例变量也是如此。
我正在尝试实现一个完成处理程序模式,其中在执行工作之前将块分配给对象,并且在执行工作后由接收器执行块。由于我是一个优秀的内存公民,块应该拥有它在完成处理程序中引用的对象,然后当块超出范围时它们将被释放。我知道我必须copy
将块移动到堆中,因为块将在声明它的堆栈范围内存活。
但是,我的一个对象意外地被释放。经过一番尝试,当块被复制到堆中时,似乎某些对象没有保留,而其他对象则保留。我不确定我做错了什么。这是我可以生成的最小测试用例:
typedef void (^ActionBlock)(UIView*);
在某些方法的范围内:
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:@"test@recipient.com",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]);
我希望这两个对象在某个时候都被块保留,我当然希望它们的保留计数相同。相反,我得到了这个输出:
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
( 的子类NSObject
) 被正确保留并且不会超出范围。但是mailViewController
不会保留,并且会在块运行之前被释放,从而导致崩溃。