ios - UITableView crashes after (apparently) failing to ask delegate for numberOfRowsInSection -
there lot of questions here uitableviewcontroller
s crashing when number of rows returned bynumberofrowsinsection
isn't consistent datasource.
my app crashing because of problem -- can't see why. add confusion, crashes on real iphone , iphone simulator works on (real) ipad.
this error:
2013-04-05 14:38:15.644 jobtime[28484:c07] *** terminating app due uncaught exception 'nsrangeexception', reason: '*** -[__nsarraym objectatindex:]: index 3 beyond bounds [0 .. 2]'
it's right -- nsarray extends 2.
what's odd tableview doesn't seem asking controller (which set delegate) number of rows in section before refreshes itself. method:
- (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { nslog(@"called numberofrowsinsection"); return [[[jobstore sharedstore] alljobs] count]; }
here's sequence crash on iphone simulator (but not ipad):
- tableview working properly, performing expected, nslog message above pops regularly.
- click 'add new item' button.
- add new item jobstore (a singleton containing nsarray of jobs).
- open modal navigationcontroller (uimodalpresentationformsheet) edit new item.
- cancel edit -- , remove unwanted item jobstore.
then crash:
- the tableview updates without calling numberofrowsinsection (i.e. nslog message above doesn't appear), tries retrieve object jobstore outside bounds of array.
i've added nslog dismissblock that's executed on completion of viewcontroller being dismissed:
[jobdetailviewcontroller setdismissblock:^{ nslog(@"dismissblock"); [[self tableview] reloaddata]; [self cleartableviewbackgroundcolorandresethighlight]; }];
that's executed when choose 'done' , save item modal view, not when choose 'cancel'. line of code same in both methods, , know correct methods being called each button:
[[self presentingviewcontroller] dismissviewcontrolleranimated:yes completion:dismissblock];
the same true if simplify dismissblock nslog statement , no other calls: doesn't called in 'cancel' case.
the solution i've found rather inelegant 1 of re-checking bounds of array in cellforrowatindexpath:
- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:@"uitableviewcell"]; if (!cell) { cell = [[uitableviewcell alloc] initwithstyle:uitableviewcellstylevalue1 reuseidentifier:@"uitableviewcell"]; } // check array bounds before trying retrieve object array if ([indexpath row] < [self tableview:tableview numberofrowsinsection:0]) { job *j = [[[jobstore sharedstore] alljobs] objectatindex:[indexpath row]]; [[cell textlabel] settext:[j displaydescription]]; [[cell detailtextlabel] settext:[j timedescription]]; if ([j selected]) { [cell setbackgroundcolor:[uicolor lightgraycolor]]; } } else { [[cell textlabel] settext:@""]; nslog(@"gone past array bounds"); } return cell; }
that works, it's clumsy. idea why tableview doesn't seem ask updated number of rows before refreshes itself? or why works on ipad, not iphone?
i'm beginning suspect quirk of different modal views grateful help. in advance.
james
uitableview
caches values can more efficient (it potentially slow ask every time -depending on how calculations).
so if change underlying datasource need let tableview
know it. can either full [self.tableview reloaddata];
or use following methods
– insertrowsatindexpaths:withrowanimation:
– deleterowsatindexpaths:withrowanimation:
– moverowatindexpath:toindexpath:
– insertsections:withrowanimation:
– deletesections:withrowanimation:
– movesection:tosection:
these used inside calls
– beginupdates
– endupdates
check docs
Comments
Post a Comment