[英]Why does release build fail and not debug?
我有一个运行良好的设备/调试版本。 当我进行发行并分发到设备上时,出现以下错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UILabel setWidth:]: unrecognized selector sent to instance 0x1605a0'
它发生在cellForRowAtIndexPath中:
cell.videoName.width = 163.0;
其中cell是自定义UITableViewCell,而videoName是UILabel。 为什么调试版本可以正常工作并释放失败? 分发版本也失败。 所有设置均针对基本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为nil。 如果我删除最后一行(设置宽度),则效果很好。
---编辑:新发现---
我发现除了调用width之外,我还可以做到这一点,并且它在发布时有效:
cell.videoName.frame = CGRectMake(10, 10, 100, 30);
那真的没有任何意义。
以我的经验,这通常是因为在调试版本而不是发行版本中分配的内存被初始化为0x00
。 因此,在发行版中,数据结构的成员之一具有一个选择器,该选择器是其他选择遗留下来的。 在调试版本中,它设置为零。
但是我不知道iPhone SDK环境是否将内存初始化为零-似乎在调试版本中更现代的开发环境0xcd
新分配的内存初始化为0xcd
而不是0x00
类的东西。
另外,您可能需要检查此StackOverflow问题。
听起来您要么具有一些副作用的调试代码(使用NSLog进行跟踪?),要么仅在较快发行版中出现了线程之间的间歇竞争状态。
因此,我将首先检查与调试有关的代码,然后检查是否有任何后台线程检查它们是否可能影响单元。
这也可能是您的cellForRowAtIndexPath重用标识符处理中的错误,有时会导致无效-但是很难理解为什么这只会在发行版中发生。 如果不了解自定义单元的设置方式,则很难发表更多评论。
它应该是:
cell.videoName.frame.size.width = 163.0;
UILabel没有width属性,它具有带有width字段的frame属性。
这也是发行失败而不是在调试中失败的原因,是发行具有与调试不同的某些目标构建设置,请查看哪些是不同的。 通常发布会进行更多优化。 这会看到您应用中的错误(例如内联代码),默认目标中的错误恰好由于运气不好而碰巧看到了内存中的好位置(或空白位置,或者恰好有一个整数,这就是您所期望的),不会引发异常,在该整数中对其进行内联可移动代码,以便您的错误现在可以访问内存中的其他位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.