简体   繁体   中英

Why does release build fail and not debug?

I have a device/debug build that works fine. When I build for release and distribute onto the device, I get this error:

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

It is occurring in cellForRowAtIndexPath:

cell.videoName.width = 163.0;

where cell is a custom UITableViewCell and videoName is a UILabel. Why would the debug build work fine and release fail? Distribution build also fails. All are set for Base SDK == iPhone OS 3.0.

To get a release build onto the phone, I'm simply changing my code signing to developer. I've also tried the distribution build through iTunes but it fails with the same error.

--- edit ---

I'm loading the cell like this:

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;

At runtime, the cell is of the custom type and videoName isn't nil. If I remove the last line (setting width), it works fine.

--- Edit: new discovery ---

I have found that rather than calling width, I can do this and it works in release:

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

That really doesn't make any sense.

In my experience this is usually because allocated memory is initialized to 0x00 in a debug build, and not in a release build. Therefore in the release build one of the members of your data structure has a selector that is leftover from something else. In the debug build it's set to zero.

But I don't know if the iPhone SDK environment initializes memory to zeroes--it seems that more modern development environments in a debug build initialize newly allocated memory to something like 0xcd instead of 0x00 .

Also, you might want to check this StackOverflow question.

It sounds like you have either got some debug code (tracing with NSLog?) that has side effects, or you have an intermittent race condition between threads that only appears in the faster release build.

So I would check firstly for debug-dependent code and then if you have any background threads check whether they might affect the cell.

It might also be a bug in your cellForRowAtIndexPath reuse identifier processing that results in a nil sometimes - but it is difficult to see why this would only happen in release builds. Without seeing how your custom cell is set up it is difficult to comment more.

It should be:

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

UILabel doesn't have a width property, it has a frame property with a width field.

also the reason it is failing in release and not in debug is that release has some target build setting that is different than debug, see which ones are different. usually release has more optimizations going on. and this will see the bug in your app, (like inlining code) where your bug in default target just happens to see a good spot in memory by bad luck on your part (or a blank spot, or just a spot that happens to have an integer in it, and that is what you were expecting) that isn't going to raise the exception, where inlining it moves the code so that your bug is now accessing someplace else in memory..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM