cellForRowAtIndexPath never called - iphone

I've subclassed UITableView to create my own data retrieval system, as described in Apple's own Core Data tutorial, but I've hit a problem. The substitute cellForRowAtIndexPath method in my custom table never gets called, not even when I call reloadData or setNeedsDisplay. I've been hunting around for solutions to this one, and it seems that this error can be caused by a multitude of problems. However I've checked all the ones I can find and cannot see anything missing. Can anyone tell me what's likely to be wrong?
P.S. I know the UITableViewDataSource protocol needs to be in triangular brackets, but I couldn't find out how to show triangular brackets on the page without deleting the text between them.
H-File
#interface DataTable : UITableView <UITableViewDataSource> {
NSMutableArray *list;
}
#property (nonatomic, retain) NSMutableArray *list;
#end
M-File
#implementation DataTable
#synthesize list;
-(id) initWithFrame:(CGRect)rect Style:(UITableViewStyle)style{
if (self = [super initWithFrame:rect style:style]){
list = [[NSMutableArray alloc] init];
self.dataSource = self;
}
return self;
}
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [list count];
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellID = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellID] autorelease];
}
CH *this = (CH *)[list objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [this.clusterName mutableCopy];
return cell;
}
-(void) dealloc{
[list release];
[super dealloc];
}
#end

Never mind, think I've found it. Basically, you can't set the datasource delegate in that part of the program. Need to do it from its owning view controller.

Related

Loading data into a uitableview in a uiviewcontroller

I am trying to load data from an array which was made by parsing json... I have the json data in the arrays for sure, but the table view methods are not even being called... I have the table view embedded in a regular uiviewcontroller, it compiles and everything the table just loads no data.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [transactions count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"any cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"any cell"] autorelease];
}
NSLog(#"got here");
cell.textLabel.text = [names objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [prices objectAtIndex:indexPath.row];
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
names = [[NSMutableArray alloc] init];
prices = [[NSMutableArray alloc] init];
[self requestTransactionData];
}
And here's my .h file...
#interface Controller1 : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
UIActivityIndicatorView *loadingIndicator;
IBOutlet UITableView *myTableView;
IBOutlet UILabel *totalLabel;
NSMutableArray *names;
NSArray *transactions;
NSMutableArray *prices;
}
#property(nonatomic, retain) IBOutlet UIActivityIndicatorView *loadingIndicator;
#property(nonatomic, retain) IBOutlet UILabel *totalLabel;
#property(nonatomic, retain) UITableView *myTableView;
I can't use ARC for this project. I also have it hooked up properly in the interface builder... These seems rather easy but for some reason I can't figure it out. Any suggestions?
Thanks
I don't see how you know the data source methods are not being called. You are not logging all of them. IfnumberOfRowsInSection is called before transactions is populated or is nil, it returns zero and that's the end of that.
Try calling reloadData using delayed performance so that it happens after transactions is populated. The table view doesn't magically know when your data is ready; you have to tell it.
call sef.tableView reloadData after names the prices were filled in requestTransactionData

NSArray released early

I'm having a problem with my iPhone app crashing when I scroll down on a UITableView. I set NSZombieEnabled to YES, and found out that the NSArray I'm using to fill the table is getting dealloced somehow.
#import "RootViewController.h"
#implementation RootViewController
#synthesize flashsets;
- (void)viewDidLoad
{
//Unrelated code removed from this post
NSString *listofsetsstring = [[NSString alloc]
initWithContentsOfFile:pathtosetsdata
encoding:NSUnicodeStringEncoding
error:&error];
flashsets = [listofsetsstring componentsSeparatedByString:#"\n"];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [flashsets 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] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
NSLog(#"IndexPath.row = %i", indexPath.row);
cell.textLabel.text = [flashsets objectAtIndex:indexPath.row]; <<<< CRASH HERE!!
return cell;
}
#end
I'm getting message sent to deallocated instance 0x4ebae20 at the bolded line. In my .h I used #property (nonatomic, retain) NSArray *flashsets;, I thought the retain part should keep it from deallocating.
How do I keep it from doing this?
Problem is with :
flashsets = [listofsetsstring componentsSeparatedByString:#"\n"];
change it to
flashsets = [[listofsetsstring componentsSeparatedByString:#"\n"] retain];
edit: the retain in property is only used if you use the setter, so it will only work if you use the following line:
[self setFlashsets:[listofsetsstring componentsSeparatedByString:#"\n"]];
in you viewDidLoad it should be self.flashsets = this will insure the accessor method is used to set the value, and thus the 'retain' behaviour you specified on the property definition will be implemented.
flashsets = [listofsetsstring componentsSeparatedByString:#"\n"];//it returns autorealesed NsArray.So If you want Longer Use.you should get Owner ship from that array By Alloc or Copy Or Retain.
flashsets = [[listofsetsstring componentsSeparatedByString:#"\n"] retain];
or
flashsets = [[listofsetsstring componentsSeparatedByString:#"\n"]copy];
or
flashsets = [[NsArry alloc ] initWithArray:[listofsetsstring componentsSeparatedByString:#"\n"]];
I don't know if this will help, but you may want to use the setter and getter methods when referring to flashsets - the retain part of the property doesn't apply (I don't think) when setting the variable directly.

Trouble Reloading UITableView

I am trying to create an iphone application that reads a json feed and I am having some trouble updating a TableView.
This is my TableViewController header file:
#interface LiveNewsController : UITableViewController <UITableViewDelegate, UITableViewDataSource>{
NSMutableData *responseData;
NSMutableArray *articleArray;
UITableView *tblView;
}
-(void) refreshPressed: (id)sender;
#property (nonatomic, retain) IBOutlet UITableView *tblView;
#end
These are some parts of my TableViewController implementation file:
#implementation LiveNewsController
#synthesize tblView;
-(id) init {
if(self = [super init])
{
self.title = #"Live News";
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"I am here %d",[articleArray count]);
return [articleArray 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] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSLog(#"cellForRowAtIndexPath called. Data size %d", [articleArray count]);
NSUInteger row = [indexPath row];
cell.textLabel.text = [articleArray objectAtIndex:row];
return cell;
}
-(void) refreshPressed: (id)sender
{
NSLog(#"Reload Pressed. Data size: %d", [articleArray count]);
[tblView reloadData];
}
Here is a screenshot of my .xib file with the connections:
So the main idea is the following:
Fetch articleArray
When refresh is pressed update view (the data is being fetched correctly but the snippet doesn't show it here)
numberOfRowsInSection and CellForRowAtIndexPath are only being called once when the view loads but nothing happens when I press the reload button.
I checked tblView and it is nil. I did some research and read that this is usually caused by some erroneous connections in the .xib file but I have triple checked that and I can't seem to pinpoint the problem.
Any help is appreciated,
Thanks!
You don't need to declare the UITableView tblView, the UITableViewController has already one (and therefore all subclasses too).
Just try [self.tableView reloadData];.

How to update numberOfRowsInSection using NSMutableArray count

In my app I allow users to add new rows of NSStrings to a UITableView. I save these new strings in an NSMutableArray *dataArray
So for numberOfRowsInSection I return [dataArray count], but it seems to just return 0 all the time so my table is not auto-populating.
If it helps, when I do an NSLog of [dataArray count] as a add more entries, it keeps remaining as 0. Why isn't it increasing?
Any help?
Without looking # your code ,it's not possible to predict the reason..
Then also you can try your HardLuck...below:
First try to NSLog your dataArray to check wether the record is adding in that or not.
It's its ok... you are getting the records.
then you are missing one thing.
reload the table..
[tableView reloadData];
I think this would definitely help you..otherwise put some code over here.
Have you initialised your Array. Here is how I've done it - prob a better way!
.h:
#interface RootViewController : UITableViewController {
NSArray *array;
}
#property (nonatomic, retain) NSArray *array;
#end
.m:
#implementation RootViewController
#synthesize array;
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *mArry = [[NSMutableArray alloc] init];
[mArry addObject:#"An ObecjT"];
self.array = mArry;
[mArry release];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [array 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] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [array objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *aNewArray = [[NSMutableArray alloc] initWithArray:array];
[aNewArray addObject:#"Your Object"];
self.array = aNewArray;
[aNewArray release];
[self.tableView reloadData];
}
- (void)viewDidUnload {
self.array = nil;
}
- (void)dealloc {
[array release];
[super dealloc];
}
Did you set the delegate for the UITableView in Interface Builder ? please check it.
If you have added, then you have to check with that dataArray whether it is having records or not.

UITableView not getting populated

I have a peculiar problem. I created a normal Objective C class called SampleTable. I then extended UITableView instead of NSObject. Then in the initWithFrame constructor I initialized the table. I also made a NSMutableArray object for the datasource. I also conformed UITableViewDelegate and UITableViewDatasource. I have overridden the necessary methods also.
Now I made an object of this class in another class, and added the object as a subview. The tableView is getting drawn according to the CGRectMake() coordinates I gave to the initWithFrame constructor. But it is not getting populated with the data. I don't know what the problem is.
SampleTable.h
#import <Foundation/Foundation.h>
#interface SampleTable : UITableView {
NSMutableArray *ItemArray;
}
#property (nonatomic,retain) NSMutableArray *ItemArray;
-(NSMutableArray *) displayItemArray;
#end
SampleTable.m
#import "SampleTable.h"
#implementation SampleTable
#synthesize ItemArray;
-(id)initWithFrame:(CGRect)frm {
[super initWithFrame:frm];
self.delegate=self;
self.dataSource=self;
[self reloadData];
return self;
}
-(NSMutableArray *) displayItemArray {
if(ItemArray==nil) {
ItemArray=[[NSMutableArray alloc] initWithObjects:#"1",#"2",#"3",#"4",#"5",nil];
}
return ItemArray;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [ItemArray count];
}
-(UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[cell autorelease];
}
NSString *temp=[self.ItemArray objectAtIndex:indexPath.row];
cell.textLabel.text = temp;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"didselect");
}
-(void) dealloc {
[ItemArray release];
[super dealloc];
}
#end
You did never initialize the ItemArray within your code snippet. Remove the displayItemData method and change the initializer towards:
-(id)initWithFrame:(CGRect)frm
{
if ((self = [super initWithFrame:frm])) != nil)
{
self.delegate=self;
self.dataSource=self;
ItemArray=[[NSMutableArray alloc] initWithObjects:#"1",#"2",#"3",#"4",#"5",nil];
[self reloadData];
}
return self;
}
You could also simply call that displayItemArray method within the initializer. I feel that method makes no sense as it stands and hence my recommendation to remove it altogether.
Without trying it myself, I am still pretty confident that you can also get rid of that [self reloadData] within the initializer.
During the -(id)initWithFrame:(CGRect)frm method your code calls -reloadData on the UITableView. At this point in time your ItemArray is not available.
Therefore, when UITableView calls it's delegates -numberOfSectionsInTableView: and -tableView:numberOfRowsInSection: methods to get information on what to display in the view, they return one section with zero rows.
Nothing displayed!
It might be a (one) solution to change your initialization of the ItemArray:
-(NSMutableArray *) displayItemArray {
if(ItemArray==nil) {
ItemArray=[[NSMutableArray alloc] initWithObjects:#"1",#"2",#"3",#"4",#"5",nil];
[self reloadData];
}
return ItemArray;
}
print value of
[self.ItemArray objectAtIndex:indexPath.row];
in NSLog... check wether it prints valid value or not....It seems that array's object releasing somewhere before it..