开发者

How to debug iPhone app crash log. Crash only in App Store purchased version, not in development

I received the first crash report but I am not able to get what is the problem. Fortunately, since this crash came from a colleague of mine, I can test the error directly on his iPhone and install a development version on his phone.

However, the strange thing is that when I install and run the development version on his device from my computer there is no crash; the crash appear only when the application is downloaded and installed from the App Store. Until now I could not reproduce the error on any other device (the affected device is an iPhone 3G firmware 4.2.1 and all the operating system run very slowly).

The crash happen after that a row is selected from a UITableViewController (ItemsListTableViewController), at this point a detail view should appear, but the application crash during the construction of the detail view (ItemDetailViewController) in viewDidLoad.

In particular the problem seem to be localized within the class LocationPathView (a subview of ItemDetailViewController's view). ItemDetailViewController is a subclass of UITableViewController and load its tableHeaderView from nib in viewDidLoad with:

[[NSBundle mainBundle] loadNibNamed:@"ItemDetailHeaderView" owner:self options:nil]; (LocationPathView is part of the tableHeaderView)

When the nib file is loaded, LocationPathView::awakeFromNib is called and then LocationPathView::layoutSubviews is called. The crash seem to be originated from layoutSubviews. Within layoutSubviews I perform an animation: [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.2]; Could this animation create for some reasons the crash on slow device? Is correct to animate within layoutSubviews?

I would be grateful for any help,

Marco

Date/Time:       2011-04-30 12:50:36.972 +0200
OS Version:      iPhone OS 4.2.1 (8C148)
Report Version:  104

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

Thread 0 Crashed:
0   libSystem.B.dylib               0x35de3ad0 __kill + 8
1   libSystem.B.dylib               0x35de3abe kill + 4
2   libSystem.B.dylib               0x35de3ab2 raise + 10
3   libSystem.B.dylib               0x35dfad5e abort + 54
4   libstdc++.6.dylib               0x374f2a00 __gnu_cxx::__verbose_terminate_handler() +    588
5   libobjc.A.dylib                 0x32d9d8d8 _objc_terminate + 160
6   libstdc++.6.dylib               0x374f0100 __cxxabiv1::__terminate(void (*)()) + 76
7   libstdc++.6.dylib               0x374f0178 std::terminate() + 16
8   libstdc++.6.dylib               0x374f02a0 __cxa_throw + 100
9   libobjc.A.dylib                 0x32d9bf28 objc_exception_throw + 104
10  CoreFoundation                  0x3759dabc +[NSException raise:format:arguments:] + 64
11  CoreFoundation                  0x3759daf0 +[NSException raise:format:] + 24
12  QuartzCore                      0x33d9409c CALayerSetPosition(CALayer*, CA::Vec2<double> const&, bool) + 180
13  QuartzCore                      0x33d93fd8 -[CALayer setPosition:] + 40
14  QuartzCore                      0x33d93efc -[CALayer setFrame:] + 444
15  UIKit                           0x358d92c8 -[UIView(Geometry) setFrame:] + 248
16  UIKit                           0x3592dde0 -[UIButton setFrame:] + 120
17  MyApp                       0x0003432a -[LocationPathView layoutSubviews] (LocationPathView.m:101)    <<<<<<<<<<<<<<<<<<<<<<<<<<<
18  UIKit                           0x358ec704 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 32
19  CoreFoundation                  0x37538f72 -[NSObject(NSObject) performSelector:withObject:] + 18
20  QuartzCore                      0x33d9a128 -[CALayer layoutSublayers] + 176
21  QuartzCore                      0x33d99db0 CALayerLayoutIfNeeded + 192
22  QuartzCore                      0x33d99cd8 -[CALayer layoutIfNeeded] + 108
23  UIKit                           0x3598ee38 -[UIView(Hierarchy) layoutIfNeeded] + 24
24  UIKit                           0x359fbabc -[UIButton titleLabel] + 76
25  MyApp                       0x0001fee8 -[ItemDetailViewController viewDidLoad] (ItemDetailViewController.m:148)     <<<<<<<<<<<<<<<<<<<<<<<<<<<
26  UIKit                           0x35926e58 -[UIViewController view] + 152
27  UIKit                           0x35937f2c -[UIViewController contentScrollView] + 24
28  UIKit                           0x35937d4c -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 36
29  UIKit                           0x35937bf8 -[UINavigationController _layoutViewController:] + 28
30  UIKit                           0x35937474 -[UINavigationController _startTransition:fromViewController:toViewController:] + 336
31  UIKit                           0x35937288 -[UINavigationController _startDeferredTransitionIfNeeded] + 256
32  UIKit                           0x35926c44 -[UINavigationController pushViewController:transition:forceImmediate:] + 904
33  UIKit                           0x359268a8 -[UINavigationController pushViewController:animated:] + 36
34  MyApp                       0x00020a9a -[ItemsListTableViewController viewItemDetail:startEditable:] (ItemsListTableViewController.m:717)
35  MyApp                       0x00022110 -[ItemsListTableViewController tableView:didSelectRowAtIndexPath:] (ItemsListTableViewController.m:241)  <<<<<<<<<<<<<<<<<<<<<<<<<<<
36  UIKit                           0x3595bf4c -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 884
37  UIKit                           0x35a5da9c -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 196
38  Foundation                      0x351724d4 __NSFireDelayedPerform + 360
39  CoreFoundation                  0x375522fe __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 10
40  CoreFoundation                  0x37551cd2 __CFRunLoopDoTimer + 982
41  CoreFoundation                  0x37521a8a __CFRunLoopRun + 1178
42  CoreFoundation                  0x37521504 CFRunLoopRunSpecific + 220
43  CoreFoundation                  0x37521412 CFRunLoopRunInMode + 54
44  GraphicsServices                0x33e76d1c GSEventRunModal + 188
45  UIKit                           0x3591d574 -[UIApplication _run] + 580
46  UIKit                           0x3591a550 UIApplicationMain + 964
47  MyApp                       0x00002fce main (main.m:14)
48  MyApp                       0x00002f98 0x1000 + 8088

ItemsListTableViewController.m:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    Item *item = [self.fetchedResultsController objectAtInd开发者_开发技巧exPath:indexPath];
    [self viewItemDetail:item startEditable:NO];    <<<<<<<<<<<<<<<<<<<
}


- (void)viewItemDetail:(Item *)item  startEditable:(BOOL)editable {
    ItemDetailViewController *controller = [[ItemDetailViewController alloc] initWithStyle:UITableViewStyleGrouped showItem:item inItemsList:[self.fetchedResultsController fetchedObjects]];   

    if (editable)
        controller.editing = YES;

    [self.navigationController pushViewController:controller animated:YES];    <<<<<<<<<<<<<<<<<<<
    [controller release];
}

ItemDetailViewController.m:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationItem.title = NSLocalizedString(@"Item details", @"Item details");
    self.navigationItem.rightBarButtonItem = self.editButtonItem;

    self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];

    // Configure the tableview
    self.tableView.sectionFooterHeight = 5.0f;
    self.tableView.allowsSelectionDuringEditing = YES;

    // Create and set the tableview header
    if (headerView == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"ItemDetailHeaderView" owner:self options:nil];    <<<<<<<<<<<<<<<<<<<<<<<<<<<

        // Item title button
        itemTitleButton.titleLabel.adjustsFontSizeToFitWidth = YES;
        itemTitleButton.titleLabel.minimumFontSize = 11.0f;
        [itemTitleButton setImageEdgeInsets:UIEdgeInsetsMake(0.0f, itemTitleButton.bounds.size.width-29.0f, 0.0f, 0.0f)];
        [itemTitleButton setTitleEdgeInsets:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 24.0f)];
        UIImage *normalImage = [[UIImage imageNamed:@"objectNameHighlighedButton.png"] stretchableImageWithLeftCapWidth:11 topCapHeight:0];
        [self.itemTitleButton setBackgroundImage:normalImage forState:UIControlStateHighlighted];

        [pathView addTarget:self action:@selector(moveButtonTouchUp:) forControlEvents:UILocationPathViewMoveControlEvent];

        // Check if the item's path should be recalculated
        if (pathView.pathList == nil) {
            pathView.pathList = pathNames;
        }

        self.tableView.tableHeaderView = headerView;

        // Save initial header height so that it can be restore navigating between items with different flags count
        tableHeaderFrameHeight = headerView.frame.size.height;
    }


    // Enable the UIToolbar at the bottom of the view controller and create its buttons
    [self.navigationController setToolbarHidden:NO animated:YES];
    self.navigationController.toolbar.barStyle = UIBarStyleBlack;
    self.navigationController.toolbar.translucent = YES;

    // [omitted part]: create toolbar items …

    // Restore editing status if the view was unloaded
    if (viewUnloaded && self.editing) {
        viewUnloaded = NO;
        // this will force setEditing:YES to be called on all tableView's subviews! (categorySectionHeaderView...)
        [self.tableView setEditing:YES];
        // ...not for tableheader!
        editableImageView.editing = YES;
        pathView.editing = YES;
    }

    // Recreate item flags
    CGRect headerFrame = headerView.frame;
    for (FlaggedItem *flagObject in self.itemBookmarkRibbons) {
        headerFrame.size.height += ITEM_SHEET_FLAG_BUTTON_HEIGHT + 8.0f;
        headerView.frame = headerFrame;

        UIButton *bookmarkRibbon = [self createBookmarkRibbon:flagObject];
        bookmarkRibbon.frame = CGRectMake(0.0f, headerFrame.size.height-ITEM_SHEET_FLAG_BUTTON_HEIGHT-8.0f, 
                                      headerFrame.size.width, ITEM_SHEET_FLAG_BUTTON_HEIGHT);

        [headerView addSubview:bookmarkRibbon];
        [headerView sendSubviewToBack:bookmarkRibbon];
    }

    // Update the table header view height
    self.tableView.tableHeaderView = headerView;
}

LocationPathView.m:

- (void)awakeFromNib {
    [super awakeFromNib];

    UIColor *color = [[UIColor alloc] initWithWhite:0.0f alpha:0.0f];
    self.backgroundColor = color;
    [color release];

    [self sendSubviewToBack:backgroundView];
    // create imageview rounded rect
    CALayer *l = [backgroundView layer];
    [l setMasksToBounds:YES];
    [l setCornerRadius:10.0];
    [l setBorderWidth:2.0];
    UIColor *borderColor = [[UIColor alloc] initWithWhite:0.65 alpha:1.0];
    [l setBorderColor:[borderColor CGColor]];
    [borderColor release];

    expanded = NO;
    buttons = [[NSMutableArray alloc] initWithCapacity:2];
    [buttons addObject:[self createButtonOfType:PVButtonTypeStart]];
    [buttons addObject:[self createButtonOfType:PVButtonTypeEnd]];
}


- (void)layoutSubviews {
#define MOVE_BUTTON_WIDTH       90.0f
#define STANDARD_BUTTON_HEIGHT  22.0f

    [super layoutSubviews];

    CGRect contentRect = self.frame;
    if (CGRectIsEmpty(contentRect))
        return;

    if ([buttons count] != [pathList count] && [pathList count] > 0) {
        [self prepareButtons];
    }


    [UIView beginAnimations:nil context:nil];  <<<<<<<<<<<<<<<<<<<
    [UIView setAnimationDuration:0.2];

    CGFloat x = 0.0f, y = 0.0f;
    CGFloat availableHSpace = 0.0f;
    UIButton *button;

    for (NSUInteger i=0; i<[self.buttons count]; i++) {
        button = [buttons objectAtIndex:i];

        if (self.isExpanded == NO && i > 0 && i <= [self.buttons count]-2)
            // hide all middle buttons
            button.alpha = 0.0f;
        else {
            button.alpha = 1.0f;
            NSString *title = [pathList objectAtIndex:i];
            CGSize size = [title sizeWithFont:button.titleLabel.font];

            CGFloat buttonWidth = size.width + 36.0f;
            // check if the button width is greater than available space, if yes set the button width equal to the available space.
            // The available space is reduced in editing move to make room for the move button.
            if (self.editing && moveButton)
                availableHSpace = contentRect.size.width - MOVE_BUTTON_WIDTH - 3.0f - 10.0f; // 10.0=space from move button
            else
                availableHSpace = contentRect.size.width;

            if (x + buttonWidth > availableHSpace)
                buttonWidth = availableHSpace - x;

            button.frame = CGRectMake(x, y, buttonWidth, STANDARD_BUTTON_HEIGHT);
            [button setTitle:title forState:UIControlStateNormal];
            y += STANDARD_BUTTON_HEIGHT + 3.0f; // vertical distance between buttons
        }

        if (self.isExpanded)
            x += 14.0f; // indentation
    }

    // setup cyan background
    backgroundView.alpha = (self.isExpanded ? 0.80f : 0.0f);
    CGRect backgroundViewFrame = backgroundView.frame;
    if (self.isExpanded) {
        // 10.0 =  5.0=y gap between backgroundView and self  +  5.0=distance between edge
        backgroundViewFrame.size.height = button.frame.origin.y + button.frame.size.height + 12.0f;
    }
    else
        backgroundViewFrame.size.height = self.frame.size.height;

    backgroundView.frame = backgroundViewFrame;

    [UIView commitAnimations];

    // set moveButton position and make it visible (put it out of animation block to avoid frame changing animation,
    // fade animation already set from caller)
    if (self.editing && moveButton) {
        moveButton.frame = CGRectMake(0.0f, 0.0f, MOVE_BUTTON_WIDTH, STANDARD_BUTTON_HEIGHT*2 + 3.0f); // 3.0=vertical space between buttons
        moveButton.center = CGPointMake(contentRect.size.width - MOVE_BUTTON_WIDTH/2 - 3.0f, contentRect.size.height/2);
        moveButton.hidden = NO;
    }
}


Being an error only the app-store version makes me suspicious of a project or target setting used to build the submission binary.

Are you using a project configuration to build the submission binary? If so, the first thing I would look for is a C macro is defined incorrectly for a release version. Or perhaps it is correct at the project-level, but incorrect at the target-level. Perhaps the end of your animation block is not correctly signalled?

Building an ad-hoc version of the app with the exact same settings as your app store version would be a good test. (Code signing would be the only difference.) Delete the old app from the device and deploy it the hard way through iTunes to be sure.


It might be your animation block blocking the main transition running behind. Try to avoid these kind of situation. For example popAviewController and just after push another this kind of situation lead to crash because you are doing another transition before previous one finished. Hope you understand.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜