我有使用块和弧线,并发现在某些情况下,iOS只在发布版本中崩溃。写代码的方式是错误的,像这样。
-(IBAction)clickedButtonA:(UIBarButtonItem*)sender event:(UIEvent*)event {
NSMutableArray *arrRows = [NSMutableArray arrayWithCapacity:0];
#warning this code only crash on Release Build.... Don't use this
NSMutableDictionary * dicRow = [NSMutableDictionary dictionaryWithCapacity:0];
[arrRows addObject:dicRow];
dispatch_block_t block = ^{
NSString *str = [NSString stringWithFormat:@"%@",[_tweet valueForKey:@"text"]];
[[UIPasteboard generalPasteboard] setString:str];
};
[dicRow setValue:block forKey:kDicKeyLinkPopBlock];
NSMutableArray *sections = [NSMutableArray arrayWithObject:arrRows];
TOVLinkPopoverViewController *controller= [[TOVLinkPopoverViewController alloc] init];
controller.arrayLink = sections;
}在其他控制器中,当我访问该块时,只有在发布版本时它才会崩溃。我知道你需要复制这个区块
[dicRow setValue:[block copy] forKey:kDicKeyLinkPopBlock];用于像NSMutableDictionary这样的非块感知类。
问题是“为什么它只在发布版本时崩溃?”我知道这“应该崩溃”,这是使用块的错误方式,但希望它在调试构建时崩溃,这样我们就可以更早地发现这种错误。
另一个问题是“是否有任何构建设置会使此代码在调试构建时崩溃?”
您可以从gitHub、https://github.com/tomohisa/iOS_PopoverMenu_Notification
请参见ViewController.m并查找注释掉的代码(仅在发布时崩溃)。
发布于 2012-05-21 04:56:17
您说得对,您需要添加[block copy]。这是因为该块是在当前堆栈帧中(即在clickedButtonA:event:中)创建的,但随后您将其添加到字典中,并可能稍后将其拉出。当您稍后将其取出并使用时,原来的堆栈帧已经消失,您将拥有一个指向某个随机内存的指针,该内存可能(很可能不会)实际上不再是该块。
当你复制数据块时,如果它当前在堆栈上,那么它会被复制到堆中,如果它已经在堆中,那么它只会保留它。这意味着你现在有了一个块,它可以在上下文之间传递,并且将是有效的。
你只在发布模式下看到它崩溃的原因是,发布模式将开启编译器优化,这将完全改变堆栈的处理方式。也许你在调试模式下很幸运,没有看到这个问题,只是你的应用程序设计的一个怪癖。
https://stackoverflow.com/questions/10263110
复制相似问题