9

I'm not sure how to explain this one. I submitted an update of one of my apps to the store yesterday. The first screenshot is how one particular screen appears running on my iPhone 3G, running iOS 4.2.1, downloaded from the App Store:

And the second image below is the exact same code, no changes have been made since the original submission, running on the exact same device tethered through Xcode.

The application runs fine on my iPhone 4, running iOS 5, downloaded from the App Store. So to recap:

  1. App obtained from App Store is flawed on iPhone 3G
  2. App obtained from App Store is good on iPhone 4
  3. App tethered through Xcode is good on iPhone 3G

These are not the only graphical inconsistencies, but they're all related to custom UITableViewCell code, which doesn't do anything more than push labels a few pixels in each directory, and has been working fine since day one. I have filed a report with idp-dts, and am waiting to hear back from them, but as the waiting list is usually a week or more, I'd rather figure this out on my own.

Any help/tips/guesses would be very appreciated!

iPhone 3G running App Store version of my application:

enter image description here

iPhone 3G running Xcode tethered version of my application:

enter image description here

Edit: This sounds quite similar to this problem: Building with LLVM and any optimization causes app to crash on startup The customer who contacted me was using a 2nd generation iPod Touch, the only other hardware other than the iPhone 3G that uses armv6.

Edit 2: Here's the snippet of code that sets the bounds of the color bar on the left side. There doesn't seem to be anything fishy going on in the code:

- (void)layoutSubviews {
    CGRect colorViewFrame = self.bounds;
    colorViewFrame.size.width = 6;
    colorViewFrame.origin.y += 3;
    colorViewFrame.origin.x -= 1;
    colorViewFrame.size.height -= 8;

    colorView.frame = colorViewFrame;
    ...
}
Community
  • 1
  • 1
Craig Otis
  • 31,257
  • 32
  • 136
  • 234
  • Which version of the SDK did you build your app against? – BoltClock Oct 12 '11 at 11:47
  • iOS 5 (the GM seed) is the Base SDK, while the deployment target was left at iOS 4.0 – Craig Otis Oct 12 '11 at 11:48
  • You say it's an update. Could it be using data saved outside the app bundle to calculate the offsets? What happens if you delete the app and re-download? – Dolbz Oct 12 '11 at 11:51
  • Deleting and re-downloading leaves me with the botched version. All the frames are calculated dynamically inside the [UITableViewCell layoutSubviews]; method, so nothing's saved outside. – Craig Otis Oct 12 '11 at 11:53
  • I'll be damned... you know what? I decided to take a look at the Build Settings for the app, comparing differences between the Debug and Release schemes. One difference was LLVM Compiler Optimization Level. Was set to "None" for Debug, and "Fastest, Smallest" for Release. I changed it to "Fastest, Smallest" for Debug and can now reproduce in the Simulator. Surely this is a bug? I don't want to submit un-optimized code to the App Store, but if optimizing my code is altering its behavior... ?? – Craig Otis Oct 12 '11 at 12:01
  • @Bavarious, sorry for any confusion. Thanks for updating to cocoa-touch. – Craig Otis Oct 12 '11 at 16:52

4 Answers4

7

So here's what I found under Build Settings:

enter image description here

Which, having taken a class or two in compiler optimization, makes sense. Code debugging on a device should be left in its original state for debugging purposes, and code released should be optimized for speed and efficiency.

So here's the fun part. Changing my Debug setting to Fastest, Smallest:

enter image description here

Causes the issue to occur on my device while running tethered in Xcode.

Before filing a Radar or making any rash decisions and submitting non-optimized code to the App Store, is there anything else I should consider investigating? Was the compiler optimization really the underlying cause of the layout issues?

Edit: And if the optimization level is the issue, why does the optimized code run properly on my iPhone 4, but not properly on my iPhone 3G?

Edit 2: This problem sounds extremely similar to this answer: Building with LLVM and any optimization causes app to crash on startup

Edit 3: Heard back from Apple Radar, this is a known issue. Will be fixed in a future version of Xcode. Thanks for all the help guys!

Community
  • 1
  • 1
Craig Otis
  • 31,257
  • 32
  • 136
  • 234
  • 3
    Sounds like a variable initialization problem – like a value that's in certain circumstances initialized for you, and at other times not. – paulmelnikow Oct 12 '11 at 13:02
  • Sounds like an optimization issue, but you should probably be testing both debug and release versions locally on your machines. Post the code that does your cell indenting and maybe someone can help. – EricLeaf Oct 12 '11 at 13:30
  • It does seem to be an optimization issue. I will make it a habit of testing both debug and release versions on both devices. I had been testing both versions on my iPhone 4, and debug versions on my iPhone 3G, but I hadn't expected issues under a single piece of hardware and a specific build scheme. Lesson learned I suppose, but it still indicates a optimization level bug, correct? I will update the original question with code. – Craig Otis Oct 12 '11 at 13:44
  • In case it wasn't clear, I'm not disagreeing. I'm suggesting what kind of optimization issue I think it is. – paulmelnikow Oct 12 '11 at 15:32
  • Yea, no I think you're right. The optimization issue is certainly affecting the [self bounds] return value, so initialization could certainly be a factor. Thanks for the help so far. – Craig Otis Oct 12 '11 at 15:56
1

I have the same issue, and have found a workaround for the problem.

I found after doing some NSLog's on the optimised and unoptimised code, that CGSize's were becoming corrupt after the first time the height parameter was accessed.

so this code was in my UITableViewCell subclass layoutSubviews:

  NSLog(@"size.height %f", size.height);
  NSLog(@"2nd access size.height %f", size.height);
  _titleLabel.frame = CGRectMake(kLeftSpacer, kSpacerHeight, kTitleWidth ,size.height);
  NSLog(@"after setFrame size.height %f", size.height);

gave the following in the log:

size.height 19.000000

2nd access size.height 56.00000

after setFrame size.height 56.00000

So, my workaround was to use an intermediate height identifier:

CGFloat height = size.height; 
NSLog(@"size.height %f", size.height);
_titleLabel.frame = CGRectMake(kLeftSpacer, kSpacerHeight, kTitleWidth ,height);
NSLog(@"after setFrame size.height %f", size.height);

and all was fine...

I guess not as safe as turning off optimisations, but the rest of my app seems fine...always best to test with release builds then!

Nick Hingston
  • 8,724
  • 3
  • 50
  • 59
  • I have almost this exact problem with CGPoint on iOS 4.2.1 with LLVM 3 and the compiler optimization turned on – Ian1971 Mar 01 '12 at 10:33
0

If you are adding and laying out views in a table view cell, you should add them to the cells's contentView and use self.contentView.bounds instead of self.bounds in all of your layout code.

You also need to call [super layoutSubviews] otherwise many strange things will happen.

Mike Weller
  • 45,401
  • 15
  • 131
  • 151
  • Thanks for the contentView note, I'll be sure to change this. (Though, I can't imagine it's the underlying issue of this problem, as changing compiler optimization levels resolves it.) I'm calling [super layoutSubviews] later in the code snippet. – Craig Otis Oct 12 '11 at 14:40
  • Well, you need to call [super layoutSubviews] as the first line in your overridden method. And I'm not saying you're wrong, but I think it's unlikely that a compiler optimization bug is the root cause of this behaviour. It's probably just exposing whatever the underlying problem it. – Mike Weller Oct 12 '11 at 15:58
0

The answer is to add a compiler flag -mno-thumb for armv6 compilations, and not to add it for armv7 compilations.

Howto is available: Is there a way to compile for ARM rather than Thumb in Xcode 4?

Community
  • 1
  • 1
Carl D'Halluin
  • 1,052
  • 10
  • 14
  • The best answer on that page also mentions: "Additionally, there is currently a bug in the LLVM Compiler 3.0 that ships with Xcode 4.2 (which has since been fixed in 4.2.1, from what I hear) where floating point calculations are compiled wrong under Thumb for ARMv6. If you're using that particular version of Xcode, you'll need to do this for proper behavior on the older devices." So I think rather than adding the compiler flag, it's easier to just upgrade to Xcode 4.2.1 – Craig Otis Jan 23 '12 at 12:37
  • Sure craig, but it requires you to upgrade to Lion – Carl D'Halluin Feb 21 '12 at 13:02