ReloadData para UITableView no funciona; tableView devuelve NULL cuando se registra

Estoy llamando a un método en mi class TableViewController desde otra class.

Para llamar al método de visualización de tableview, hago esto:

TableViewController *tableVC = [[TableViewController alloc]init]; [tableVC setTableViewContent]; 

luego en TableViewController.h

 @interface TableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> { NSMutableArray *nameArray; } -(void)setTableViewContent; @property (nonatomic, strong) IBOutlet UITableView *tableView; @end 

TableViewController.m

 @implementation TableViewController @synthesize tableView; - (void)viewDidLoad { nameArray = [[NSMutableArray alloc]init]; [super viewDidLoad]; } -(void)setTableViewContent{ AppDelegate *appDelegate = (AppDelegate *)[[UIApplication shanetworkingApplication] delegate]; for(int i=0;i< [appDelegate.businessArray count];i++) { NSDictionary *businessDict = [[appDelegate.businessArray objectAtIndex:i] valueForKey:@"location"]; nameArray = [appDelegate.businessArray valueForKey:@"name"]; } NSLog(@"%@", nameArray); NSLog(@"tableview: %@", tableView); // here tableview returns null [tableView reloadData]; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return [nameArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"updating tableview..."); static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Configure the cell... cell.textLabel.text = [nameArray objectAtIndex:indexPath.row]; return cell; } 

Por alguna razón, cuando bash registrar la vista de tabla, devuelve nulo, por lo que ReloadData no funciona. El delegado y la fuente de datos están conectados correctamente en IB, y hay una salida de reference para tableView.

¿Alguna idea de lo que está pasando aquí? Gracias por adelantado

Si agregó el controller de vista de tabla a una vista de contenedor, puede get una reference a ese controller en prepareForSegue. Para un controller en una vista de contenedor, prepareForSegue se llamará justo antes de la vista del controller primario, DidLoad, por lo que no necesita hacer nada para invocarla. En mi ejemplo a continuación, he llamado a segue "TableEmbed": necesitas dar a segue ese identificador en IB.

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if([segue.identifier isEqualToString:@"TableEmbed"]) { TableViewController *tableVC = (TableViewController *)segue.destinationViewController; [tableVC setTableViewContent]; } } 

Tenga en count que prepareForSegue: remitente: se invoca antes de que se llame a la vista del controller a la que se ha llamado DidLoad, por lo que debe mover la initialization de su matriz a setTableViewContent, y su tabla de reload debería ir a viewDidLoad.

BTW, de todos modos no me queda claro por qué quieres llamar a setTableContent desde tu otra class. ¿Por qué no mover todo el código de ese método al método viewDidLoad del controller de vista de tabla?

Esto está sucediendo porque está invocando un método en tableView antes de que realmente exista. Simplemente inicializar esa class no dibuja la tabla misma, por lo que usar reloadData antes de que la tabla realmente se haya creado realmente no tiene ningún sentido.

Lo que quiere hacer en esta situación es crear su nombreArray en la class que llame a setTableViewContent, y luego pasarlo en un método de inicio personalizado o estableciendo tableVC.nameArray antes de cargar ese controller de vista de tabla.

Lo que haría sería hacer un método init personalizado como - (id)initWithArray:(NSMutableArray *)nameArr

Cuál debería ser algo así:

 if (self = [super init]) { nameArray = [nameArr copy]; } return self; 

Entonces, donde tiene TableViewController *tableVC = [[TableViewController alloc]init]; poner TableViewController *tableVC = [[TableViewController alloc]initWithArray:theNameArray]; donde theNameArray es el contenido de setTableViewContent (que ahora está generando en la misma class que llama a la vista de tabla en lugar de a la vista de tabla en sí).

¿Tener sentido?

Resolví una situación similar creando un método de recarga "seguro" en el UITableViewController :

 - (void)reloadTableViewData { if ([self isViewLoaded]) [self.tableView reloadData]; } 

De acuerdo con los documentos de isViewLoaded :

Llamar a este método informa si la vista está cargada. A diferencia de la propiedad de vista, no intenta cargar la vista si aún no está en la memory.

Por lo tanto, es seguro llamar a reloadTableViewData en el controller de vista de tabla en cualquier momento.