【问题标题】:Why does release build fail and not debug?为什么发布构建失败而不是调试?
【发布时间】:2009-06-30 15:00:19
【问题描述】:

我有一个运行良好的设备/调试版本。当我构建发布并分发到设备上时,我收到此错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UILabel setWidth:]: unrecognized selector sent to instance 0x1605a0'

发生在 cellForRowAtIndexPath:

cell.videoName.width = 163.0;

其中单元格是自定义 UITableViewCell,videoName 是 UILabel。为什么调试构建工作正常而发布失败?分发构建也失败了。全部为 Base SDK == iPhone OS 3.0 设置。

要在手机上发布版本,我只是将代码签名更改为开发人员。我也尝试过通过 iTunes 构建发行版,但失败并出现同样的错误。

--- 编辑---

我正在像这样加载单元格:

static NSString * QuestionCellIdentifier = @"QuestionCellIdentifier";
TopicCellController *cell = (TopicCellController *)[tableView dequeueReusableCellWithIdentifier:QuestionCellIdentifier];

if(cell == nil){
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TopicCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];
}

cell.videoName.width = 163.0;

在运行时,单元格是自定义类型,并且 videoName 不为零。如果我删除最后一行(设置宽度),它工作正常。

--- 编辑:新发现---

我发现我可以这样做,而不是调用宽度,它可以在发布中工作:

cell.videoName.frame = CGRectMake(10, 10, 100, 30);

这真的没有任何意义。

【问题讨论】:

    标签: iphone xcode iphone-sdk-3.0 build


    【解决方案1】:

    根据我的经验,这通常是因为分配的内存在调试版本中初始化为0x00,而不是在发布版本中。因此,在发布版本中,您的数据结构的成员之一有一个选择器,该选择器是从其他东西中遗留下来的。在调试版本中,它被设置为零。

    但我不知道 iPhone SDK 环境是否将内存初始化为零——似乎在调试版本中更现代的开发环境会将新分配的内存初始化为 0xcd 而不是 0x00

    另外,您可能想查看this StackOverflow question.

    【讨论】:

    • 您提供的链接适用于 Visual Studio。请注意,这是 iPhone/Xcode。
    • 是的,这个链接是针对 Visual Studio 的,但是如果不一样的话,概念是相似的。
    • 感谢@Jared 的回答。 +1 我们在最近的一个项目中遇到了这个问题,其中团队成员没有初始化一些 int 变量。
    【解决方案2】:

    听起来您要么有一些具有副作用的调试代码(使用 NSLog 跟踪?),要么您在线程之间存在间歇性竞争条件,仅出现在较快的版本构建中。

    所以我会首先检查依赖于调试的代码,然后如果您有任何后台线程,请检查它们是否会影响单元格。

    这也可能是您的 cellForRowAtIndexPath 重用标识符处理中的一个错误,有时会导致 nil - 但很难理解为什么这只会在发布版本中发生。如果不了解您的自定义单元格是如何设置的,就很难发表更多评论。

    【讨论】:

    • 我编辑了一些附加信息来解决您的 cmets。谢谢。
    【解决方案3】:

    应该是:

    cell.videoName.frame.size.width = 163.0;
    

    UILabel 没有宽度属性,它有一个带有宽度字段的框架属性。

    【讨论】:

      【解决方案4】:

      它在发布而不是在调试中失败的原因是发布有一些与调试不同的目标构建设置,看看哪些不同。通常发布有更多的优化。这将在您的应用程序中看到错误(如内联代码),您的默认目标中的错误恰好在您的运气不佳(或空白点,或恰好有的点)中看到内存中的一个好点一个整数,这就是您所期望的)不会引发异常,内联它会移动代码,以便您的错误现在正在访问内存中的其他位置..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-03
        • 2019-06-18
        • 2012-09-19
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多