UITableView reloadData does nothing (UITableView is not zero)

I am building my first application, and you guys were already most helpful, but I struggled with the fact that tableView is not updating. I hope that someone here can shed some light on this and maybe come up with some ideas on other things that might have been missed or made unnecessarily complicated.

Now the application should do the following:

  • Fill the table with data from sqlite db (basically just list all the tables)
  • The user clicks a button (which launches the fetchData method)
  • (void) fetchData compares local db with db server checksums
  • (void) fetchData installs NSURLConnection, communicating with the server via POST
  • When the connection has received all the data, it updates the local db
  • TableView dataSource (which is NSMutableArray) is updated with new db data
  • The lookup table is updated and lists all the tables in the database [myTableView reloadData] called

Things I checked twice: the connections between the table view and the delegate, the data source and the output; that tableView is not zero; that the data source itself has been accurately updated;

Everything works to the last point (7). It seems that myTableView at that time is not zero. Ideas? And please tell me if you need to know more about my code.

I also looked a little at the beginUpdates and endUpdates methods, but it seems to me that they focus on a few changes and user interactivity. I would like to simply reload the entire table based on user options (i.e., I would like to reflect the whole SQL selection string depending on the current user login). Or is there another, even better way to do this?

Thanks in advance!

Here's a pretty good piece of code:

#import "FirstViewController.h" @interface FirstViewController () @end @implementation FirstViewController #import "FirstViewController.h" @synthesize myTextView, myTableViewDataSource, myFetchedData, resultat, tablesAndChecks, tablesArr, checksArr, tablesToRequest,receivedData, receivedDataString, SQL, sqlStatementsArr, failedSqlStatementsArr, failedSqlStatementsCodeArr, dbloop1; #pragma mark Table view methods - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } // Customize the number of rows in the table view. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSLog(@"Konfigurerar tableView"); //swedish for "Configuring tableView" if(myTableView.dataSource==nil){ NSLog(@"datasource = nil"); }else{ NSLog(@"datasource != nil"); //This prints in log } NSLog(@"%d",[myTableViewDataSource count]); //prints "19" in log return [myTableViewDataSource count]; } // Customize the appearance of table view cells. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"calling cellForRowAtIndexPath"); //This does NOT print in log static NSString *CellIdentifier = @"myCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } // Set up the cell... cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:15]; cell.textLabel.text = [NSString stringWithFormat:@"Tabell %d: %@", [indexPath row], [myTableViewDataSource objectAtIndex:[indexPath row]]]; return cell; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"connection did finish loading"); //... //script that receives a long SQL-string from the server //and then updates the database with it goes here //... //Ok, so now the database has updated correctly, and it time //to update the tableview so that it reflects the new data. // //Get data from database... NSMutableArray * tempArray = [[NSMutableArray alloc] initWithCapacity:0]; if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) { NSLog(@"Databasen รถppnad"); NSString *beginSQL = [NSString stringWithFormat: @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"]; const char *begin_stmt = [beginSQL UTF8String]; sqlite3_prepare_v2(contactDB, begin_stmt, -1, &statement, NULL); while(sqlite3_step(statement) == SQLITE_ROW) { char *col1 = (char *)sqlite3_column_text(statement, 0); if (col1 !=NULL){ [tempArray addObject:[NSString stringWithUTF8String: col1]]; } } if (sqlite3_step(statement) == SQLITE_DONE) { NSLog(@"#####%s; Done: %@", sqlite3_errmsg(nil), beginSQL); } else { NSLog(@"#####%s; Error with string: %@; Errcode: %d Errmsg: %s", sqlite3_errmsg(nil), beginSQL, sqlite3_errcode(contactDB), sqlite3_errmsg(nil)); } NSLog(@"%d", sqlite3_finalize(statement)); sqlite3_close(contactDB); //update the datasource to the values of tempArray myTableViewDataSource = tempArray; //Some logging to see that the updated data is in the array... (which it is) NSLog(@"myTableViewDataSource count: %d",[myTableViewDataSource count]); for (i=0; i<[myTableViewDataSource count]; i++) { NSLog(@"%@",[myTableViewDataSource objectAtIndex:i]); } } //Finally, check so that myTableView isn't nil and can receive messages if(myTableView == nil){ NSLog(@"NILCHECK mytableview is nil!"); }else{ NSLog(@"NILCHECK mytableview is NOT nil!"); //This is printed out to the log } //Reload data -> nothing happens... [myTableView reloadData]; } - (void)fetchData { //function that gets current checksums for all db tables on the server, compares them to the local database //and then requests an SQL-string from the server to update the tables that needs it. //I don't think this is relevant for my problem, and it runs fine anyways. //The last thing it does is setting up a NSURLConnection to communicate with //the server (sending which tables to request via POST and then getting the SQL-string as the server response) NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self]; if (theConnection) { //receivedData = [NSMutableData data]; NSLog(@"ReceivedData รคr: %d", [receivedData length]); } else { NSLog(@"Connection Failed!"); } //All done here, now the ReceivedData method takes over } } 

Update:

This is my viewDidLoad method:

 - (void)viewDidLoad { //creates database and fills "tempArray" with data NSLog(@"%d", sqlite3_finalize(statement)); sqlite3_close(contactDB); myTableViewDataSource = tempArray; NSLog(@"myTableViewDataSource count: %d",[myTableViewDataSource count]); for (i=0; i<[myTableViewDataSource count]; i++) { NSLog(@"%@",[myTableViewDataSource objectAtIndex:i]); } } myTableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain]; myTableView.delegate = self; //Added this after comment (1) myTableView.dataSource = self; //Added this after comment (2) } 

Update: After that:

 myTableView.delegate = self; myTableView.dataSource = self; 

tableView:numberOfRowsInSection: is called to view tableView:numberOfRowsInSection: , and dataSource is not zero, but tableView:cellForRowAtIndexPath: not called, and the table is not updated.

Update 2: Here is my header file:

  // // FirstViewController.h // OHBSYS Storyboards // // Created by David Forsberg on 2012-09-25. // Copyright (c) 2012 David Forsberg. All rights reserved. // #import <UIKit/UIKit.h> #import <sqlite3.h> @interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>{ NSString *databasePath; sqlite3 *contactDB; UITextView *myTextView; UITableView *myTableView; NSMutableArray *myTableViewDataSource; NSMutableString * tableRowCount; NSMutableArray * dbloop1; //And a bunch of other variables here } @property (retain, nonatomic) IBOutlet UITextView *myTextView; @property (nonatomic, retain) IBOutlet UITableView *myTableView; @property (nonatomic, retain) IBOutlet NSMutableArray *myTableViewDataSource; - (IBAction) fetchData; @property (nonatomic) NSString * tableRowCount; @property (nonatomic, retain) NSMutableArray * dbloop1; //A bunch of other properties here as well @end 

Update 3:

I tried to check the values โ€‹โ€‹with breakpoints.

Breakpoint inside the table: numberofrowsinsection:

 (lldb) po self.myTableView (UITableView *) $0 = 0x0d13ca00 <UITableView: 0xd13ca00; frame = (0 20; 768 1004); clipsToBounds = YES; layer = <CALayer: 0x2a3d30>; contentOffset: {0, 0}> (lldb) po self.myTableView.delegate (objc_object *) $1 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableView.dataSource (objc_object *) $2 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableViewDataSource (NSMutableArray *) $3 = 0x0029fb20 <__NSArrayM 0x29fb20>( CONTACTS, sqlite_sequence ) (lldb) 

Breakpoint after db update, just before the reloadData call:

 (lldb) po self.myTableView (UITableView *) $4 = 0x0d13ca00 <UITableView: 0xd13ca00; frame = (0 20; 768 1004); clipsToBounds = YES; layer = <CALayer: 0x2a3d30>; contentOffset: {0, 0}> (lldb) po self.myTableView.delegate (objc_object *) $5 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableView.dataSource (objc_object *) $6 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableView.dataSource //(accidentally hit that twice) (objc_object *) $7 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableViewDataSource (NSMutableArray *) $8 = 0x0ce6baa0 <__NSArrayM 0xce6baa0>( CONTACTS, meta_tablechecksums, prot_multicoltest, prot_multicoltest_4, prot_multicoltest_4_desc, prot_multicoltest_desc, sqlite_sequence, superadmin_filefolders, superadmin_files, superadmin_imagefolders, superadmin_images, sys_customers, sys_fieldlooks, sys_fieldtypes, sys_formtables, sys_pages, sys_subpages, sys_userroles, sys_users ) (lldb) 

Breakpoint AT reloadData:

 (lldb) po self.myTableView (UITableView *) $9 = 0x0d13ca00 <UITableView: 0xd13ca00; frame = (0 20; 768 1004); clipsToBounds = YES; layer = <CALayer: 0x2a3d30>; contentOffset: {0, 0}> (lldb) po self.myTableView.delegate (objc_object *) $10 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableView.dataSource (objc_object *) $11 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableViewDataSource (NSMutableArray *) $12 = 0x0ce6baa0 <__NSArrayM 0xce6baa0>( CONTACTS, meta_tablechecksums, prot_multicoltest, prot_multicoltest_4, prot_multicoltest_4_desc, prot_multicoltest_desc, sqlite_sequence, superadmin_filefolders, superadmin_files, superadmin_imagefolders, superadmin_images, sys_customers, sys_fieldlooks, sys_fieldtypes, sys_formtables, sys_pages, sys_subpages, sys_userroles, sys_users ) (lldb) 

Breakpoint inside tableview: numberofrowsinsection: after updating db and executing reloadData command:

 (lldb) po self.myTableView (UITableView *) $13 = 0x0d13ca00 <UITableView: 0xd13ca00; frame = (0 20; 768 1004); clipsToBounds = YES; layer = <CALayer: 0x2a3d30>; contentOffset: {0, 0}> (lldb) po self.myTableView.delegate (objc_object *) $14 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableView.dataSource (objc_object *) $15 = 0x0ce99500 <FirstViewController: 0xce99500> (lldb) po self.myTableViewDataSource (NSMutableArray *) $16 = 0x0ce6baa0 <__NSArrayM 0xce6baa0>( CONTACTS, meta_tablechecksums, prot_multicoltest, prot_multicoltest_4, prot_multicoltest_4_desc, prot_multicoltest_desc, sqlite_sequence, superadmin_filefolders, superadmin_files, superadmin_imagefolders, superadmin_images, sys_customers, sys_fieldlooks, sys_fieldtypes, sys_formtables, sys_pages, sys_subpages, sys_userroles, sys_users ) (lldb) 
+7
source share
3 answers

The main problem with this was the lack of a controller in the MVC application. I read the basic concept and built it again from scratch - this time, the right way.

0
source

I do not see how myTableView is synthesized. Also called tableView table source methods when doing reloadData?

If not, double check and make sure the myTableView delegate is set correctly. If you correctly connected the table to the tip, and you have a socket, you can install it also in the code, that is, in the viewDidLoad method, by setting:

 myTableView.delegate = self; 
+2
source

@Lefteris was right. You may already have this, but I do not see your header file. In the view controller header file, add a property to save the link to the table view:

@property (nonatomic, strong) UITableView *myTableView;

Then in your implementation file:

@synthesize myTableView = myTableView_;

Finally, in the implementation file, change all tableview references from myTableView to self.myTableView and see if you suddenly begin to receive delegate callbacks.

+2
source

All Articles