Reputation: 4764
I am populating a tableview with the contents of an array. Right now, I create the array in viewdidload and I calculate the number of rows in the delegate method
//in viewdidload
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kItemsURL];
[self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];
});
[self.tableView reloadData];
//method called in viewdidload to create array...
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSLog(@" %@",json);
NSArray* latestItems = [json objectForKey:@"items"];
NSLog(@" array:%@",latestItems);
//getItems is a property in .h file
self.getItems = latestItems;
NSLog(@"getItems %@",_getItems); //logs out array ok
int size = [_getItems count];
NSLog(@"there are %d objects in the array", size);//provides correct number
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"getItems %@",_getItems); //logs (null)
int size = [_getItems count];
NSLog(@" %d objects in the array", size);//logs 0
When I count rows in viewdidload after creating the array, I get the correct number, however, when I call count
on the array in the delegate method, it returns zero possibly because the tableview is created before Viewdidload is called.
Where should I create the array so that is known by the time numberofrows counts the number of rows in the array?
Edit:
After constructing the array, I save it to a property. However, I have discovered that this property is empty when I then log it to console in the numberofrowsinsection method so the problem seems to lie in how I am storing this array.
Right now, I have a property in the .h file and I've also tried it in the implementation but either way it is not persisting for some reason.
Upvotes: 0
Views: 898
Reputation: 317
I suggest to load the content of your array in viewDidLoad(), that is called once and before the table view use the array. The table view do not load the items before viewDidLoad. Are you doing something much different than this example structure below?
@implementation ViewController {
NSArray *arrayList;
}
- (void)viewDidLoad {
[super viewDidLoad];
arrayList = @[@"item 1", @"item 2"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = [arrayList objectAtIndex:indexPath.row];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return arrayList.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
Upvotes: 1
Reputation: 402
I'm not to familiar with obj-C, but I know you need to initialize your array outside your viewDidLoad()
function. The reason why your .count
is returning zero, is because your array is acting as a local variable to your viewDidLoad()
function. Instead you could initialize the array as field in your UITableViewController
class. This is how you would do so in swift, but it applies to obj-C as well:
class YourTableViewController: UITableViewController {
var yourArray = [AnyObject]()
override func viewDidLoad() {
//You can still do any programming to set up values and elements in yourArray[] here
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourArray.count
}
//Plus all your other tableView functions...
}
Also if you are passing information to your array between other UIViewController
's you can add this function to your class, so every time you come back to your table view it loads the correct table cell count:
override func viewWillAppear(animated: Bool) {
self.tableView.reloadData()
}
Upvotes: 1
Reputation: 426
Consider abstracting the creation of your data - the array instantiated in your tableview, into a model instead. This is generally considered to be a better software engineering practice (read : https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html ).
What I would do is have another file as a Class or Struct, and populate the data for the array used in your table view in there. I would also recommend having setter/getter methods in your array class/struct as well. When loading the tableview, we would then grab the data from the class/struct in your tableview viewDidLoad() method. The data from your array would also be available at any other point of your application as well, as it is no longer dependant on the tableview.
Side note : You can consider making the class/struct a singleton as well, if the model is supposed to only get instantiated once.
Upvotes: 0