iOS 5仅使用Release Build阻止崩溃 [英] iOS 5 blocks crash only with Release Build

查看:93
本文介绍了iOS 5仅使用Release Build阻止崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用过块和ARC,并且在某些情况下发现,iOS仅在Release版本中崩溃。这是编写代码的错误方法,如下所示。

I have using blocks and ARC, and found in some situation, iOS only crash in Release build. It was wrong way to write code, like this.

-(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;
}

从其他控制器,当我访问该块时,它只会崩溃我是在发布版本上。我知道你需要复制块

And from other controller, when I access the block, it crashes only I am on release build. I have learn you need to copy the block

[dicRow setValue:[block copy] forKey:kDicKeyLinkPopBlock];

对于非块识别类,如NSMutableDictionary。

For non-block aware Class like NSMutableDictionary.

问题是为什么它只会在发布版本上崩溃?我知道这应该崩溃,这是使用块的错误方法,但希望它在Debug构建时崩溃,所以我们可以在之前找到这种bug。

The question is "Why it only crashes on Release build?" I know this "should crash", and this was wrong way of using block, but hoping it crashes on Debug build so we can find this kind of bug earlier.

一个更多问题是是否有任何构建设置使代码在调试版本中崩溃?

One more question is "Is there any build setting that makes this code crash with debug build?"

您可以从gitHub运行示例代码,
https://github.com/tomohisa/iOS_PopoverMenu_Notification

You can ran sample code from gitHub, https://github.com/tomohisa/iOS_PopoverMenu_Notification

参见ViewController.m并找到注释掉的代码(仅在发布时崩溃)。

See ViewController.m and find commented out code (only crash on release).

推荐答案

你是对的,你需要添加 [块复制] 。这是因为该块是在当前堆栈帧中创建的(即在 clickedButtonA:event:中),但随后您将其添加到字典中,并可能稍后将其拉出。当您稍后将其拉出并使用它时,原始堆栈帧已经消失,您将有一个指向某些随机内存的指针,这些内存可能不再(很可能不会)实际上是该块。

You're right that you need to add [block copy]. This is because that block is created in the current stack frame (i.e. within clickedButtonA:event:) but then you add it to a dictionary and presumably pull it out later. When you pull it out later and use it, that original stack frame has gone and you will have a pointer to some random memory that might not (most likely won't) actually be the block any more.

当你复制块时,如果它当前在堆栈上,那么它会被复制到堆中,如果它已经在堆上,那么它就会保留它。这意味着你现在有一个可以在上下文之间传递并且有效的块。

When you copy the block, if it's on the stack currently then it gets copied to the heap and if it's already on the heap then it just retains it. This means that you now have a block which can be passed around between contexts and will be valid.

你只是看到它在发布模式下崩溃的原因是因为发布模式将启用编译器优化,这完全改变了堆栈的处理方式。可能你在调试模式下非常幸运,没有看到问题,只是对你的应用程序设计的一个怪癖。

The reason that you are only seeing it crash in release mode is because release mode will be turning on compiler optimisation that is completely changing how the stack is handled. Probably you were very lucky in debug mode not to see the problem and was simply a quirk of how your app is designed.

这篇关于iOS 5仅使用Release Build阻止崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆