`[[self tableView] reloadData]` changes the NSMutableArray count - iphone

I have an app that uses a UITablewView and in that TableView there is an NSMutableArray that holds the data to be displayed in the TabelView.
The problem is in my TableView Controller I use:
[[self tableView] reloadData]
To reload the TableView data and it works fine for a couple of times but doesn't work on the 3rd time and instead it changes the array count in a weird way.
Now I read similar question here and most likely I have 2 instances of the TableView or the TableViewController but I can't figure out how to troubleshoot this? How to detect if there are 2 instances of the object and fix that?
EDIT: Here is a pic how my navigation goes
So the 1st round of going from ScrollView to TableView things show up correctly. Then I go to UIView and back to TableView and it's working fine. So I go back all the way to ScrollView and back again to TableView and it's good.
But when I go to the UIView for this time then back to TableView this problem happens. TableView doesn't display the changes. So I put a breakpoint just before [[self tableView] reloadData] and found out that the array _displayedObjetcs gets its count changed. -1 actually. see the following screen shots b4 and after I step over the reloadData
and then

My immediate thought is that your array is not being retained properly, by your application. Your "weird" count is probably a number like 234791..., which is highly indicative of an array that has been released incorrectly. Therefore, I would check how your are retaining and releasing this array.
However, without more posted code, it is impossible to help you further.

Related

Reloading a table's data

I have 5 view controllers, which are in a navigation controller hierarchy. When I reach my last view controller, there's a button that lets me go back to the "Home" view controller (named CardWalletViewController) which is a table view controller. Here's the method I have in my last VC (PointsResultsVC)
- (IBAction)homePressed:(id)sender {
NSArray *VCs = [self.navigationController viewControllers];
[self.navigationController popToViewController:[VCs objectAtIndex:0] animated:YES];
}
CardWalletVC's cells is being filled up by values coming from the saved instances of a Card in NSUserDefaults and it works fine.
Now, what I want is to update the value in my CardWalletViewController, which is the points of a card coming from my PointsResultsVC. Note that this points is saved in NSUserDefaults.
Upon the process of trying to update of the value shown in my CardWalletVC, I placed [self.tableView reloadData]; inside -viewDidLoad, -viewWillAppear, and -viewDidAppear of the said class. I tried placing it one by one in each of this methods, yet it doesn't seem to work.
Advice Please.
EDIT: problem solved
This one served as my guide Save data from one tab and reloadData in another tab.
And as I have discovered, -viewDidLoad of a certain class will only be called once, all throughout runtime of app. Whereas -viewWillAppear, it will be called every time the view appears.
So, I just moved the way I am loading the values saved in NSUserDefaults from -viewDidLoad to -viewWillAppear. Also, inside -viewWillAppear I placed the [self.tableView reloadData]. Then there, problem solved.
There's a lot of things that could be going wrong so you'll need to provide more info to narrow it down.
First of all, viewDidLoad will not be called so you can remove it from here. Both viewWillAppear and viewDidAppear will be called, so you only need it one of these 2 methods.
Next, you need to determine what the actual issue is.
1 - is self.tableView a proper reference to the table? Are you properly maintaining the reference?
2 - is the table actually reloading but using the old data, or is it not reloading at all? You can log the willDisplayCell method to see what is going on when the view appears.
With that info, the root cause can be narrowed down to a solvable problem.

iphone - scrollRectToVisible issue

This functions perfectly, but I want to make it an once-function, not fixed-function. When I change tableview with other data, the data displays at the index from previous tableview. So my solution to this is implementing the code below. When I implement this, it works, but when I scroll down, it scrolls up all the time, so it is virtually impossible to scroll down further. Any idea how to make it performs only once when I change tableview?
The code:
[tableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
Edit 21 august:
Guys, thank you very much! The code was in cellforrowatindexpath. I moved it to inside the function which changes tableview and it works like a charm :D
You could override the reloadData method if that is how you are reloading the Table View with new data and put the code in there. Something like this in your table view controller should suffice:
- (void)reloadData {
[super reloadData];
[tableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}
If it's scrolling up every time you scroll down, I assume you put the code in the cellForRowAtIndexPath method which will get called every time you want to present the cell. This is not the correct place to put that code.
It IS a once-function. Most probably, this code of yours is executing again & again. If you have kept this in a function such as cellForRowAtIndexPath:, which is called frequently, that may be the cause of this problem. Where have you put it?
HTH,
Akshay

cellForRowAtIndexPath returns nil on device

I spent few hours trying to resolve one very strange issue, but I really don't know how to proceed.
I have a grouped UITableView referenced from XIB populated with custom (subclassed) UITableViewCell cells. All the cells (two section with one cell each) are visible and I am trying to get one of them by calling:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
LocationSearchFilterCell *cell = (LocationSearchFilterCell *)[filterTable cellForRowAtIndexPath:indexPath];
On Simulator 4.2 the cell is returned properly;
On Device 4.0.x the code returns NIL;
On Simulator 4.0.x the code returns NIL;
On Simulator 4.1 the cell is returned properly BUT NOT on Device 4.1.
The strangest thing is that I am using this approach on few other places within the application and the cell is always returned properly. I guess it is some strange combination of me doing something differently combined with some iOS bug.
Any idea ?
P.S. In situation where NIL is returned, by using GDB I get the pointer of the cell when it is created and call:
(gdb) po (void *)[filterTable indexPathForCell:(UITableViewCell *)0x7b08520]
and I get a valid index path (that matches the one I am providing) which means the cell is valid and present into the table view.
I have even tried passing the object returned by this last call (by pointer) and I still get NIL.
Interesting,
It turned out someone is hiding the table view before I try to get the cell (stupid me :)).
What I was doing was, triggering an animation to hide the table view (nested into some methods I am calling from the method where I try to get the cell). Because I was stopped on a breakpoint the animation was also stopped, so it seamed to me like the table view is visible.
What I don't understand still is why the table view is threaded as hidden although the animation is still not finished (and I only change the frame in the animation and set the table hidden after the animation is finished) ?
I guess the answer to this question is the key point why on different combinations of Device / Simulator / iOS I get different behavior. Anyway the solution is as simple as moving the two lines I've posted above at the top of the method.
Thanks to Rits for his question that triggered my reasoning ;)
regards

UiTableView records Problem

i Have some problem. i have 25 records in my NSMutableArray and i want to display them 5 records at a time when user press Next button then another 5 records to display and when user press back button then previous 5 records to display.
How can i do this any help from you would be great.
Thank You.
Make an ivar in your table view controller that tracks which records you should display. Set the ivar in your Next/Back buttons action method and send [self.tableView reloadData]. Use the ivar in -tableView:numberOfRowsInSection: and -tableView:cellForRowAtIndexPath: to determine how many and which cells to display.
First of all, I recommend against this design. Tableviews on iPhone apps are great to scroll with your fingers, and having buttons like this defeats this. However, I don't know what you're doing, so I'll assume it's cool.
My suggestion is to use slices of the larger array as follows:
- (NSArray *)itemsForPage:(NSUInteger)p {
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(5*p,5)];
return [_thatOneLargeArray objectsAtIndexes:indexes];
}
Note that I've refactored this code into a method. Let me know if this is helpful!

Problem reloading UITableView

I have a UITableView which is populated by an array, I have a button on the navigaton bar which (when pressed) adds an item to the array and calls [self.tableView reloadData] in the UITableView. This results in numberOfRowsInSection being called and returning the correct number of rows (the number of items in the array) BUT doesn't call cellForRowAtIndexPath.
I have created a new navigation based application to try and find a solution but have exactly the same problem!
If anyone knows the answer it would be greatly appreciated, i've been tearing what's left of my hair out for the last day!
I have put the source for the test project up on my site at www.sofaracing.com/Downloads/Test3.zip
Works for me! ;)
In MainWindow.xib, You added an object Root View Controller (that's not part of the Navigation Controller) - Delete it, not necessary. Then connect outlet refreshFriendsList to the Bar Button of the NavigationItem of RootViewController. Wha-la, magic!
BTW: You may need to clean up the warning. And you might want to think about creating a class for your data model instead of using UIApplication sharedApplication.
I quickly debugged your test app. I couldnt't spot the root cause, but it seems that you have two different table views due some mess up in Interface Builder setup.
If you initialize original array with an item, cellForRowAtIndexPath is correctly called. If you examine self.tableView instance in this call and later in subsequent calls to refreshFriendsList, self.tableView points to a different instance.
2009-05-17 14:33:07.591 Test3[33580:20b] cellForRowAtIndexPath 0
2009-05-17 14:33:07.594 Test3[33580:20b] self.tableView: <UITableView: 0x52b9b0>
2009-05-17 14:42:36.810 Test3[33762:20b] numberOfRowsInSection: tableView <UITableView: 0x53bcd0>