title: iOS (iPhone/iPad) SDK - UITableView not refreshing on reloadData (numberOfSectionsInTableView etc. does not get called on reloadData)
body: <p>For some reason <code>[tView reloadData]</code> (where tView is a UITableView) does not refresh my UITableView. <code>cellForRowAtIndexPath</code>, <code>numberOfSectionsInTableView</code> and <code>numberOfRowsInSection</code> only get called once - at load. Those methods don't seem to be called after <code>[tView reloadData]</code>. Here's my code:</p>
  
  <p>(AppDelegate.h):</p>
  
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  #import "MBProgressHUD.h"
  
  @class FirstNavViewController;
  @class SecondTableViewController;
  
  @interface &lt;appname&gt;AppDelegate : NSObject &lt;UIApplicationDelegate, MBProgressHUDDelegate&gt; {
      UIWindow *window;
      UITabBarController *rootController;
      FirstNavViewController *viewController;
      SecondTableViewController *viewController1;
      NSMutableData *responseData;
      NSMutableArray *blogEntries;
      MBProgressHUD *HUD;
  }
  
  @property (nonatomic, retain) IBOutlet UIWindow *window;
  @property (nonatomic, retain) IBOutlet UITabBarController *rootController;
  @property (nonatomic, retain) IBOutlet FirstNavViewController *viewController;
  @property (nonatomic, retain) IBOutlet SecondTableViewController *viewController1;
  @property (nonatomic, retain) NSMutableArray *blogEntries;
  @end
  </code></pre>
  
  <p>(AppDelegate.m):</p>
  
  <pre><code>#import "AppDelegate.h"
  #import "FirstNavViewController.h"
  #import "SecondTableViewController.h"
  #import "SBJson.h"
  #define TMP NSTemporaryDirectory()
  
  @implementation AppDelegate
  
  @synthesize window = _window;
  @synthesize rootController;
  @synthesize viewController;
  @synthesize viewController1;
  @synthesize blogEntries;
  
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
      // Override point for customization after application launch.
      CGFloat width = self.rootController.view.bounds.size.width;
      CGFloat height = self.rootController.view.bounds.size.height;
      UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, width, height)];
      UIImage *imageView = [UIImage imageNamed:@"theme_frame.png"];
      UIColor *kMainColor = [[UIColor alloc] initWithPatternImage:imageView];
  
      [v setBackgroundColor:kMainColor];
      [kMainColor release];
      [self.rootController.tabBar insertSubview:v atIndex:0];
      imageView = nil;
      [v release];
  
      responseData = [[NSMutableData data] retain];
      blogEntries = [NSMutableArray array];
      NSURLRequest *request = [NSURLRequest requestWithURL:
                               [NSURL URLWithString:@"ENTER_JSON_URL_HERE"]];
      [[NSURLConnection alloc] initWithRequest:request delegate:self];
  
      NSAssert(nil != self.rootController, @"tab bar controller not hooked up!");
  
      BOOL iPad = NO;
  #ifdef UI_USER_INTERFACE_IDIOM
      iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
  #endif
  
      if (iPad) {
          self.viewController = [[[FirstNavViewController alloc] initWithNibName:@"FirstNavViewController_iPad" bundle:nil] autorelease];
          self.viewController1 = [[[SecondTableViewController alloc] initWithNibName:@"SecondTableViewController_iPad" bundle:nil] autorelease];
      }
      else {
          self.viewController = [[[FirstNavViewController alloc] initWithNibName:@"FirstNavViewController_iPhone" bundle:nil] autorelease];
          self.viewController1 = [[[SecondTableViewController alloc] initWithNibName:@"SecondTableViewController_iPhone" bundle:nil] autorelease];
      }
  
      self.rootController.viewControllers = [NSArray arrayWithObject:self.viewController];
  
      self.rootController.selectedIndex = 0;
  
  #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
      self.window.rootViewController = self.rootController;
  #else
      [self.window addSubview:rootController.view];
  #endif
  
      [self.window makeKeyAndVisible];
  
      HUD = [[MBProgressHUD alloc] initWithView:viewController.view];
      [viewController.view addSubview:HUD];
      [HUD show:NO];
  
      // Regisete for HUD callbacks so we can remove it from the window at the right time
      HUD.delegate = self;
  
      HUD.labelText = @"Loading";
  
      return YES;
  }
  
  #pragma mark NSURLConnection delegate methods
  - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
      [responseData setLength:0];
  }
  
  - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
      [responseData appendData:data];
  }
  
  - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
      [HUD hide:YES];
      [connection release];
  }
  
  - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
      [connection release];
      NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
      [responseData release];
  
      NSMutableArray *allBlogEntries = [responseString JSONValue];
      [viewController1 setBlogEntries:allBlogEntries];
      [responseString release];
      [HUD hide:YES];
  
  }
  
  - (void)dealloc
  {
      [_window release];
      [rootController release];
      [viewController release];
      [viewController1 release];
      [super dealloc];
  }
  
  @end
  </code></pre>
  
  <p>(FirstNavViewController.h):</p>
  
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  
  @interface FirstNavViewController : UIViewController {
      UINavigationController *navController;
  
  }
  @property (nonatomic, retain) UINavigationController *navController;
  @end
  </code></pre>
  
  <p>(FirstNavViewController.m):</p>
  
  <pre><code>#import "FirstNavViewController.h"
  #import "SecondTableViewController.h"
  
  @implementation FirstNavViewController
  
  @synthesize navController;
  
  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  {
      self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
      if (self) {
          // Custom initialization
          UITabBarItem *tabBarItem = [self tabBarItem];
          UIImage *tabBarImage = [UIImage imageNamed:@"blog.png"];
          [tabBarItem setImage:tabBarImage];
          [tabBarItem setTitle:@"Blog"];
      }
      return self;
  }
  
  - (void)didReceiveMemoryWarning
  {
      // Releases the view if it doesn't have a superview.
      [super didReceiveMemoryWarning];
  
      // Release any cached data, images, etc that aren't in use.
  }
  
  #pragma mark - View lifecycle
  
  - (void)viewDidLoad
  {
      [super viewDidLoad];
      // Do any additional setup after loading the view from its nib.
      navController = [[UINavigationController alloc] initWithRootViewController:self];
      SecondTableViewController *secondViewController = [[SecondTableViewController alloc] initWithNibName:@"BlogOverviewViewController_iPhone" bundle:nil];
      [navController pushViewController:secondViewController animated:NO];
      [blogOverviewViewController release];
      [self.view addSubview:navController.view];
  }
  
  - (void)viewDidUnload
  {
      [super viewDidUnload];
      // Release any retained subviews of the main view.
      // e.g. self.myOutlet = nil;
  }
  
  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  {
      // Return YES for supported orientations
      return (interfaceOrientation == UIInterfaceOrientationPortrait);
  }
  
  @end
  </code></pre>
  
  <p>(SecondTableViewController.h):</p>
  
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  #import "SBJson.h"
  
  @interface SecondTableViewController : UIViewController {
      NSMutableArray *blogEntries;
      IBOutlet UITableView *tView;
  }
  @property (nonatomic, retain) NSMutableArray *blogEntries;
  @property (nonatomic, retain) NSArray *arryData;
  @property (nonatomic, retain) IBOutlet UITableView *tView;
  @end
  </code></pre>
  
  <p>(SecondTableViewController.m):</p>
  
  <pre><code>#import "SecondTableViewController.h"
  #import "ThirdDetailViewController.h"
  #import "NSString+HTML.h"
  
  NSString *convertedString;
  
  @implementation SecondTableViewController
  
  @synthesize arryData;
  @synthesize tView;
  
  
  -(NSMutableArray*)blogEntries {
      return [[blogEntries retain] autorelease];
  }
  
  -(void)setBlogEntries:(NSMutableArray*)newBlogEntries {
      if(newBlogEntries != blogEntries) {
          [newBlogEntries retain];
  
          [blogEntries release];
          blogEntries = newBlogEntries;
  
          [tView reloadData];
      }
  }
  
  #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 {
      return [blogEntries count];
  }
  
  // Customize the appearance of table view cells.
  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  
      static NSString *CellIdentifier = @"Cell";
  
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil) {
          cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
      }
  
      // Set up the cell...
      NSDictionary *aBlogEntry = [blogEntries objectAtIndex:[indexPath row]];
      NSArray *bPosts = (NSArray *)[aBlogEntry objectForKey:@"posts"];
  
      NSString *stringToConvert = [bPosts valueForKey:@"title_plain"];
      NSString *convertedString = [stringToConvert stringByConvertingHTMLToPlainText];
  
      cell.textLabel.text = convertedString;
      cell.textLabel.adjustsFontSizeToFitWidth = YES;
      cell.textLabel.font = [UIFont systemFontOfSize:12];
      cell.textLabel.minimumFontSize = 10;
      cell.textLabel.numberOfLines = 4;
      cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
  
      NSString *stringToConvert1 = [bPosts valueForKey:@"excerpt"];
      NSString *convertedString1 = [stringToConvert1 stringByConvertingHTMLToPlainText];
  
      cell.detailTextLabel.text = convertedString1;
  
      return cell;
  }
  
  
  #pragma mark -
  #pragma mark Table view delegate
  
  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      ThirdDetailViewController *detailViewController = [[ThirdDetailViewController alloc] initWithNibName:@"BlogContentViewController_iPhone" bundle:nil];
      [self.navigationController pushViewController:detailViewController animated:YES];
      NSDictionary *aBlogEntry = [blogEntries objectAtIndex:[indexPath row]];
      NSArray *bPosts = (NSArray *)[aBlogEntry objectForKey:@"posts"];
  
      NSString *stringToConvert = [bPosts valueForKey:@"title"];
      NSString *convertedString = [stringToConvert stringByConvertingHTMLToPlainText];
  
      [contentViewController changeTitleTextLabel:convertedString];
  
      NSString *stringToConvert1 = [bPosts valueForKey:@"content"];
      NSString *convertedString1 = [stringToConvert1 stringByConvertingHTMLToPlainText];
  
      NSString *newConvertedString1 = [convertedString1 stringByReplacingOccurrencesOfString: @"\n" withString:@"\n\n"];
  
      [detailViewController changeContentTextLabel:newConvertedString1];
  
      [tableView deselectRowAtIndexPath: indexPath animated: YES];
  }
  
  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  {
      self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
      if (self) {
          // Custom initialization
      }
      return self;
  }
  
  - (void)didReceiveMemoryWarning
  {
      // Releases the view if it doesn't have a superview.
      [super didReceiveMemoryWarning];
      // Release any cached data, images, etc that aren't in use.
  }
  
  #pragma mark - View lifecycle
  
  - (void)viewDidLoad
  {
      [super viewDidLoad];
      // Do any additional setup after loading the view from its nib.
      blogEntries = [[NSMutableArray alloc]init];
      self.title = @"Blog";
      [self.navigationItem setHidesBackButton:YES animated:NO];
  }
  
  - (void)viewDidUnload
  {
      [super viewDidUnload];
      // Release any retained subviews of the main view.
      // e.g. self.myOutlet = nil;
  }
  
  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  {
      // Return YES for supported orientations
      return (interfaceOrientation == UIInterfaceOrientationPortrait);
  }
  
  - (void)dealloc {
      [blogEntries release];
      [super dealloc];
  }
  
  @end
  </code></pre>
  
  <p>Does anyone know what the problem is? I am stuck on why the UITableView will not reloadData.</p>
  
  <p><strong>EDIT:</strong> Small background: I am using a UITabBarController (AppDelegate) with a UIViewController in it with a UINavigationController as a subview of that UIViewController (FirstNavViewController). The UINavigationController then has a subview with another UIViewController in it. The latter UIViewController (SecondTableViewController) includes a UITableView.</p>