UA-17470720-3

Jump to content


Photo
- - - - -

Weird crash in getHeaderTitleForItemAtIndex:


  • Please log in to reply
10 replies to this topic

#1 Gerald K.

Gerald K.

    Sr. Member

  • STV 5.0 Std
  • PipPipPip
  • 40 posts
Reputation: 5
Good

Posted 09 November 2015 - 04:26 AM

Hi,

 

I'm still not sure if this is my error or something in the framework. But since I've been bashing my head against it for at least a day now I thought I'd post something, maybe any of you can make sense of it:

 

All I do is populate a simple SCArrayOfObjectsSection via a web service. So I call the web service and in a completion block I fill the objects into the backing array, then reloadBoundValues and reloadTable to display the new objects.

 

This is the callback block:

    void (^didRequestBlock)(NSMutableArray *) = ^(NSMutableArray *content) {
        
        if (blockSelf.hud && blockSelf.hud.isVisible) {
            [blockSelf.hud dismissAnimated:NO];
        }
        
        if(blockSelf.nextOffset == 0 && blockSelf.bestellungsArray.count > 0) {
            [blockSelf.bestellungsArray removeAllObjects];
        }
        blockSelf.nextOffset = blockSelf.nextOffset + content.count;
        
        for(id order in content) {
            if ([order isKindOfClass:[CrmOrder class]]) {
                CrmOrder* myOrder = (CrmOrder*)order;
                [blockSelf.bestellungsArray addObject:myOrder];
            }
        }
        [blockSelf.tableViewModel reloadBoundValues];
        [blockSelf.tableViewModel.tableView reloadData];
    };

 

 

The crash report I sometimes get is the following:

 

*** -[__NSArrayM objectAtIndex:]: index 9223372036854775807 beyond bounds for empty array

 

 

screenshot2.png

 

 

My code ends at line 9, where I call 

[blockSelf.tableViewModel reloadBoundValues]

 

Then STV takes over.

The funny index in the crash reason sounds like LLONG_MAX, not sure if this is maybe some kind of default value of STV.

 

 

If you need any more information, please tell me.

 

 

Thanks,

Gerald


Edited by Gerald K., 09 November 2015 - 04:38 AM.


#2 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 09 November 2015 - 06:53 AM

Hi Gerald,

 

9223372036854775807 as well as being NSIntegerMax is NSNotFound. If STV is creating a new item then indexPath.row will equal NSSNotFound. I wouldn't expect it to appear on a reloadBoundValues.

 

 

Do each of your CrmOrder objects have values for their properties as expected?

 

Is your blockSelf.bestellungsArray empty?

 

How are you telling STV about your data?

 

How are you telling STV about your header title?


Cheers,

Dave

www.dgapps.ie

#3 Gerald K.

Gerald K.

    Sr. Member

  • STV 5.0 Std
  • PipPipPip
  • 40 posts
Reputation: 5
Good

Posted 09 November 2015 - 12:09 PM

Hi Dave,

 

thanks for taking the time to reply. I'll try to answer your questions:

 

1. Yes, my objects have properties, not all of the will be set at all times, but the important ones that are displayed in the SCArrayOfObjects list are there. (To add to that: I do not actually show a detailView of these objects, I have a fullscreen overlay viewController for editing and adding items. New items are first sent to the server from the fullscreen controller and then this list is refreshed, grabbing the new objects from the server in turn.

 

2. The blockSelf.bestellungsArray may be empty at times, e.g. when a user hasn't added any orders yet. It will never be nil though, because it gets initialized at viewDidLoad of the ViewController.

 

3. My definition for the SCArrayOfObjectsSection is as follows:

    __weak typeof(self) blockSelf = self;
    self.navigationBarType = SCNavigationBarTypeNone;
    self.bestellungsArray = [NSMutableArray array];
    self.tableViewModel.detailViewController = (SCTableViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
    
    SCClassDefinition *bestellDef = [SCClassDefinition definitionWithClass:[CrmOrder class] propertyNames:@[@"ordernumber",@"order_date",@"shipping_date",@"finished",@"sendConfirmation",@"status",@"accountName"] propertyTitles:@[@"Bestellnummer",@"Bestelldatum",@"Lieferdatum",@"Bereits geliefert",@"Status",@"Kunde"]];
    
    [bestellDef propertyDefinitionWithName:@"order_date"].type = SCPropertyTypeDate;
    [bestellDef propertyDefinitionWithName:@"order_date"].attributes = [SCDateAttributes attributesWithDateFormatter:[[User sharedInstance] dbDateFormatter] datePickerMode:UIDatePickerModeDateAndTime displayDatePickerAsInputAccessoryView:YES];
    [bestellDef propertyDefinitionWithName:@"shipping_date"].type = SCPropertyTypeDate;
    [bestellDef propertyDefinitionWithName:@"shipping_date"].attributes = [SCDateAttributes attributesWithDateFormatter:[[User sharedInstance] outputDateFormatter] datePickerMode:UIDatePickerModeDateAndTime displayDatePickerAsInputAccessoryView:YES];
    
    bestellDef.requireEditingModeToEditPropertyValues = YES;
    [self.tableViewModel setEnablePullToRefresh:YES];
    
    bestellDef.cellActions.didLayoutSubviews = ^(SCTableViewCell *cell, NSIndexPath *indexPath) {
        [cell respondsToSelector:@selector(textField)] ? [[(SCTextFieldCell *)cell textField] setTextAlignment:NSTextAlignmentRight] : nil;
    };
    
    SCArrayOfObjectsSection *bestellSection = [SCArrayOfObjectsSection sectionWithHeaderTitle:@"Meine Bestellungen" items:self.bestellungsArray itemsDefinition:bestellDef];
    bestellSection.allowDeletingItems = YES;
    [self.tableViewModel addSection:bestellSection];

 

4. I have no custom header titles (which is why I am even more puzzled about the crash line). I have custom cells though, not sure it that is connected, but I would think not:

self.tableViewModel.sectionActions.cellForRowAtIndexPath = ^SCCustomCell *(SCArrayOfItemsSection *section, NSIndexPath *indexPath) {
        SCCustomCell *customCell = [SCCustomCell cellWithText:nil objectBindingsString:@"1:combinedLine;2:account_name1_c;3:account_name2_c" nibName:@"ThreeLineCell"];
        return customCell;
    };

 

 

Thanks,

Gerald



#4 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 10 November 2015 - 02:48 AM

Hi Gerald,

 

​I can't see anything wrong with your code at all.

 

​As far as I can work out STV notices that you've modified an item, so calls itemModified:inSection: but then can't find the item in getSectionIndexForItem: so passes NSNotFound to getHeaderTitleForItemAtIndex:  which then crashes.

 

I'm not sure if getHeaderTitleForItemAtIndex: should check for NSNotFound or not, that's a Tarek thing...

 

 

And for some reason your array of items is empty, is that expected?

 

 

 

 

Sorry, I'm not not much help I'm afraid.


  • Tarek likes this
Cheers,

Dave

www.dgapps.ie

#5 Gerald K.

Gerald K.

    Sr. Member

  • STV 5.0 Std
  • PipPipPip
  • 40 posts
Reputation: 5
Good

Posted 10 November 2015 - 05:47 AM

Hi Dave,

 

it is quite an odd thing, so no worries about not being able to help.

 

The array could of course be empty, if the user hasn't added any orders yet. So he/she would refresh the list via the STV refresh control and my web service would not return anything to add to the backing array. Which then in turn should result in an empty list. I'm sure this is working fine since all my users started off with an empty list at first.

 

 

The point that's most peculiar to me is that I cannot reproduce the crash myself at all. It only happens to some of my users, very rarely, about once a week.



#6 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 10 November 2015 - 09:48 AM

I agree, it seems really odd, and I am not even sure where to start guessing. If you're able to replicate using your code, I'd be more than happy to have a look at your project or a similar sample.



#7 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 10 November 2015 - 10:20 AM

Hi Tarek,

 

 

If getHeaderTitleForItemAtIndex: checked for NSNotFound STV could avoid the crash couldn't it? But I'm not sure of any other implications of doing that.

 

It's strange that STV knows the item has been modified, but then can't find the modified item immediately afterwards... And not being able to replicate the crash makes it somewhat more difficult to work out what's happening of course...


Cheers,

Dave

www.dgapps.ie

#8 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 10 November 2015 - 11:19 AM

Hi Dave,

 

The thing is, this should never happen. STV simply traverses the SCArrayOfObjectsModel items array and calls 'getHeaderTitleForItemAtIndex:' for each one of them. There is no search operation involved that would return NSNotFound. Placing a check there anyways would only hide a much bigger problem.



#9 Gerald K.

Gerald K.

    Sr. Member

  • STV 5.0 Std
  • PipPipPip
  • 40 posts
Reputation: 5
Good

Posted 10 November 2015 - 12:12 PM

Hi Tarek, Dave,

 

I will try to isolate this viewController in its own project and test it till it breaks on my watch. I can't explain it, since I can't see any of my code modifying the items array while it is being traversed by STV.

I do network stuff, then add new items (or not, if none are returned), then call reloadBoundValues. There is no multithreading going on past the networking portion returning.

 

I will upload the project once I have it ready.

 

Thanks,

Gerald



#10 Dave Guerin

Dave Guerin

    Forum Master

  • STV 5.0 Pro
  • PipPipPipPipPipPipPip
  • 539 posts
  • LocationIreland
Reputation: 134
Popular

Posted 11 November 2015 - 08:53 AM

Hi Tarek,
 
If I'm reading STV code correctly getSectionIndexForItem: is using the NSArray method indexOfObjectIdenticalTo: to get the index of the item, so there is a type of search happening. Then, according to the crash log, the itemsArray is empty, so indexOfObjectIdenticalTo: returns NSNotFound. So the question is why does STV have an item but an empty itemsArray?
 
 
Hi Gerald,
 
You said:
 

There is no multithreading going on past the networking portion returning.

 
Is the web service callback block not on the main thread? NSMutableArray is not thread safe according to here:
 
https://developer.ap...etySummary.html
 
 
And then any UI updates should be on the main thread, so I'd also make sure reloadBoundValues and reloadData were  on the main thread, if your call back is on a different thread.
 
You also said:

 

I do not actually show a detailView of these objects, I have a fullscreen overlay viewController for editing and adding items.

 

 

 

But STV is dismissing a detailView of some sort. Is your user on a slow connection and the update from the web taking a long time and the user has gone off to another part of the app before the web service call back happens? Could that result in a empty itemsArray?

 

 

Just some thoughts.


  • Tarek likes this
Cheers,

Dave

www.dgapps.ie

#11 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 11 November 2015 - 01:29 PM

Hi Dave,

 

You're actually correct here. The case I was talking about above was the initialization phase when SCArrayOfObjectsModel is trying to get the header titles for all its sections in order to generate them, traversing all items in the 'items' array. What you correctly pointed out is another path via 'getSectionIndexForItem' where there is actually search and it's indeed the cause of the crash. Thing is, this should also not happen unless somehow the 'item' passed to 'getSectionIndexForItem' isn't in 'items', which STV should never do. @Gerald: Are you at all manually adding any items directly into your sections?


  • Dave Guerin likes this




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users