I've spent literally weeks trying to get sections and rows to work in my table and have finally did it!
Next I noticed that even though I had plenty of data to view, I could not scroll down past what is first displayed on screen. Additionally, the scroll bar seems to be fatter than usual and there is a number 2 displayed in the upper right hand corner.
Not sure what I'm doing wrong. Can someone lead me nudge me in the right direction?
I couldn't capture the fat scroll bar, but it is definitely wider than it should be.
- (void)setupFetchedResultsController {
NSString *entityName = #"Regster";
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"addDate" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)]];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Regster" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
//[request setFetchBatchSize:2];
self.fetchedResultsController.delegate = nil;
[request setPropertiesToFetch:[NSArray arrayWithObjects:#"addDate", #"regType", nil]];
NSString *query = self.selectedAccounts.name;
request.predicate = [NSPredicate predicateWithFormat:#"inAccounts.name CONTAINS[cd] %#", query];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"addDate" cacheName:nil];
[self performFetch];
NSError *error = nil;
NSUInteger count = [_managedObjectContext countForFetchRequest:request error:&error];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupFetchedResultsController];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo name];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Account Register";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
[self.tableView setScrollEnabled:YES];
NSDictionary *regtype = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [regtype objectForKey:#"regType"];
return cell;
}
EDIT1: Changing #"addDate" of the sectionNameKeyPath of the fetchedResultsController, results in the removing of the dates and sections, leaving one section and the scroll works fine. Leaving the #"addDate" does what I want with sections, but I don't understand why it doesn't scroll with that 2 and a "fat" scroll.
EDIT2: I found my problem... I had borrowed code from another instructional course to get my CoreDataTableViewController working and it had implemented sectionIndexTitlesForTableView. Commented out and is working!
It's difficult not seeing your code or understanding what the data is. But I can help a little.
That 2 in the corner is your table view's section index column (that also might be what you mean by fat scroll bar). You've got 2 sections both starting with the number 2. If the section titles were words, you'd see an alphabetical index.
The fact that the index is only showing 1 value though may mean that your table view does not show the complete data set that you're expecting, only the 2 sections you have on the screen.
Perhaps show some code? Even just the setup code might be helpful. Typically the CoreDataTableViewController needs an NSFetchedResultsController, a title key and so on. Showing some of that code might provide more clues.
I found my problem... I had borrowed code from another instructional course to get my CoreDataTableViewController working and it had implemented sectionIndexTitlesForTableView. Did some massive searching and found this brought up somewhere. Commented out the sectionIndexTitlesForTableView method and it is working perfectly!
Related
I'm trying to populate a tableview controller with objects from 2 different arrays but it crashes and gives this error
"Terminating app due to uncaught exception 'NSRangeException', reason: ' -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]"***
how do i fix this? below is my code:
(void)viewDidAppear:(BOOL)animated{
//[super viewDidAppear:<#animated#>];
NSManagedObjectContext *bookmanagedObjectContext = [self managedObjectContext];
NSFetchRequest *bookfetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Book"];
NSPredicate *bookpredicate =[NSPredicate predicateWithFormat:#" bookref.toproject contains[cd]%#",self.projectdb];
[bookfetchRequest setPredicate:bookpredicate];
NSSortDescriptor *booksortDescriptor = [[NSSortDescriptor alloc]initWithKey:#"authorSurname" ascending:YES];
NSArray *booksortDescriptors = [[NSArray alloc]initWithObjects:booksortDescriptor, nil];
[bookfetchRequest setSortDescriptors:booksortDescriptors];
self.BookrefArray = [[bookmanagedObjectContext executeFetchRequest:bookfetchRequest error:nil] mutableCopy];
NSManagedObjectContext *journalmanagedObjectContext = [self managedObjectContext];
NSFetchRequest *journalfetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Journal"];
NSPredicate *journalpredicate =[NSPredicate predicateWithFormat:#" journalref.toproj contains[cd]%#",self.projectdb];
[journalfetchRequest setPredicate:journalpredicate];
NSSortDescriptor *journalsortDescriptor = [[NSSortDescriptor alloc]initWithKey:#"surname" ascending:YES];
NSArray *journalsortDescriptors = [[NSArray alloc]initWithObjects:journalsortDescriptor, nil];
[journalfetchRequest setSortDescriptors:journalsortDescriptors];
self.JournalrefArray = [[journalmanagedObjectContext executeFetchRequest:journalfetchRequest error:nil] mutableCopy];
[self.tableView reloadData];}
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return (self.BookrefArray.count + self.journalrefArray.count);
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cells";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Journal *myjournal =[self.journalrefArray objectAtIndex:indexPath.row];
[cell.detailTextLabel setText:[myjournal valueForKey:#"journalname"]];
[cell.textLabel setText:[NSString stringWithFormat:#"%#, %#",[myjournal valueForKey:#"surname"],[myjournal valueForKey:#"firstname"]]];
Book *mybook =[self.BookrefArray objectAtIndex:indexPath.row];
// Configure the cell...
[cell.detailTextLabel setText:[mybook valueForKey:#"bookTitle"]];
[cell.textLabel setText:[NSString stringWithFormat:#"%#, %#",[mybook valueForKey:#"authorSurname"],[mybook valueForKey:#"authorOthernames"]]];
return cell;
}
You have this error because you try to access of an element of your array that is not exist.
In fact you says that your table has "table1.count + table2.count" elements and for each cell you try to get an element in your 2 tables with the current row.
For example, if table1 has 2 items and table2 has 5 items
, your tableView will have 7 rows and "cellForRowAtIndexPath" will be called 7 times. So for index 3 you will obtains this error because your table1 has only 2 items.
To solve the problem, you should get a book OR a journal in function of this row.
For example, you can try anything like this :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cells";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (indexPath.row < self.BookrefArray.count)
{
Book *mybook =[self.BookrefArray objectAtIndex:indexPath.row];
// Configure your cell with a book
}
else
{
Journal *myjournal =[self.journalrefArray objectAtIndex:indexPath.row - self.BookrefArray.count];
// Configure your cell with a journal
}
return cell;
}
You can also change the order to display journals before books.
Answer :
You need to differentiate Book and Journal in -cellForRowAtIndexPath.
Explanation :
Your call for tableview's -cellForRowAtIndexPath will be dependent upon the number you're returning from tableview's -numberOfRowsInSection method.
So, for example, you've 3 objects in BookrefArray and 2 objects in journalrefArray, your tableview's -numberOfRowsInSection method will return 5 which means -cellForRowAtIndexPath will be called for 5 times.
Let's go through this line :
Journal *myjournal =[self.journalrefArray objectAtIndex:indexPath.row];
Here, it'll get indexPath.row = 5 for one case, and your journalrefArray contains only 2 objects. So, you're getting "index .. beyond bounds" error.
Update :
You can simply merge both the arrays into one.
[documentsArray addObjectsFromArray:self.BookrefArray];
[documentsArray addObjectsFromArray:self.journalrefArray];
and then in -cellForRowAtIndexPath, you can do something like this :
id document = [documentsArray objectAtIndex:indexPath.row];
if ([document isKindOfClass:Book])
{
Book *mybook = (Book *)document;
// Do something with mybook.
}
else
{
Journal *myjournal = (Journal *)document;
// Do something with myjournal.
}
I am having trouble getting sections with a NSFetchedResultsController working. I have an entity, say 'Employee' and a string attribute, let's say 'name'. Now I want to show all employee's names in a UITableView using a NSFetchedResultsController... no problem, heres my Code:
if (_fetchedResultsController == nil) {
NSManagedObjectContext *moc = [appDelegate managedObjectContext];
NSFetchRequest *request = [NSFetchRequest new];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Employee" inManagedObjectContext:moc];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
[request setEntity:entity];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:#"name" cacheName:#"root"];
NSError *error;
[_fetchedResultsController performFetch:&error];
if (error != nil) {
NSLog(#"Error: %#", error.localizedDescription);
}
}
But the NSFetchedResultsController creates a section for each entity. So when I have 200 employees, it creates 200 sections. Why?
And how do I implement those methords properly:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [[_fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[[_fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
- (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];
}
// Configure the cell...
cell.textLabel.text = [[_fetchedResultsController objectAtIndexPath:indexPath] valueForKey:#"name"];
return cell;
}
May I do understand the whole concept wrong? Where is the difference between [_fetchedResultsController sections] and [_fetchedResultsController sectionIndexTitles]?
I hope you can help me and thanks in advance!
EDIT: I forget to tell you the most important thing: I want to have sections separated by the first letter of the 'name' attribute. (Like the Music-APP).
Nick
Pass nil as your sectionNameKeyPath when initializing your NSFetchedResultsController.
If you pass name, you basically say "please create one section for each name". When passing nil, you tell it to create only a single section.
You tableview method implementations look right to me.
[_fetchedResultsController sections] gives you an array with objects that you can ask for things like the number of objects in a section. In contrast, [_fetchedResultsController sectionIndexTitles] is mostly so you can tell the NSFetchedResultsController which section titles to use (i.e you would set this to an array with one string for each section). In your case, you can just ignore it.
Actually i'm using only one section. I sort my data stored in core data by date.
I want to have two sections (latest and history). In my first section "latest" I want to put my latest date and in the other section "history" i want to put other dates sorted by date.
My table is editable and I'm using NSFetchedResultsController.
Here is my sample code for numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Info"
inManagedObjectContext:self.managedObjectContext]];
// Define how we want our entities to be sorted
NSSortDescriptor* sortDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"date" ascending:NO] autorelease];
NSArray* sortDescriptors = [[[NSArray alloc] initWithObjects:sortDescriptor, nil] autorelease];
[fetchRequest setSortDescriptors:sortDescriptors];
NSString *lower = [mxData.name lowercaseString];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"(name = %#)", lower];
[fetchRequest setPredicate:predicate];
NSError *errorTotal = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&errorTotal];
if (errorTotal) {
NSLog(#"fetch board error. error:%#", errorTotal);
}
return [results count];
[fetchRequest release];
[results release];
}
You need to modify your designated "UITableViewDataSource" object to return "2" for the "numberOfSectionsInTableView:" method.
Then you need to return the right thing in your "tableView:cellForRowAtIndexPath:" method, depending on the section designated in the index path.
If you want an optional section title (e.g. "History" or "Latest"), you can also return an array of section titles via sectionIndexTitlesForTableView:.
Implement - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
This way the tableviewController know's how many sections to create. If you don't implement this method it will create the default number of sections which is 1.
This method is asked to the data source to return the number of sections in the table view.
The default value is 1.
The full method description can be found here
Update:
When the tableview is asking you which cell to display for a certain index path you can give the cell with the right data. Presuming you have 2 NSArray's containing the titles for the latest and history rows you could do the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//create cell
static NSString *CellIdentifier = #"MyCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(indexPath.section == 0){
//set title for latest
NSString *title = [[self latestTitles] objectAtIndex:indexPath.row];
[[cell textLabel] setText:title];
}else{
//set title for history
NSString *title = [[self historyTitles] objectAtIndex:indexPath.row];
[[cell textLabel] setText:title];
}
//Update: add NSLog here to check if the cell is not nil..
NSLog(#"cell = %#", cell);
return cell;
}
Previously, I had a large-ish dataset (~530 records) being displayed in a tableview. The data was held in an array of dictionaries with two keys, ID and name. Previously, I tapped a cell, it added a check mark, and it sent the cell row number to a 'selectedArray'. As I had already alphabetically sorted them (still in one section), the indexPath.row which was stored in the selectedArray corresponded to the dictionaries' array index, so I could pull data (the ID) from the record.
I decided that I would split this into headers by alphabetical order (which was an absolute pain, I don't see why it's such a complex process to insert headers into a list of records). But now, as I only used indexPath.row, when I tick the first one, it ticks the first record of each section, and only returns the number 0, so I only get the first record in the whole dataset. Is there a simple way to correct this? Really appreciate any help.
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"inviteCell"];
// cell.accessoryType = UITableViewCellAccessoryCheckmark;
if ([checkedCells objectForKey:[NSNumber numberWithInt:indexPath.row]] != nil) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
// NSDictionary *friend = [sortedFriendsArray objectAtIndex:indexPath.row];
//---get the letter in the current section---
NSString *alphabet = [nameIndex objectAtIndex:[indexPath section]];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF.name beginswith[c] %#", alphabet];
NSArray *states = [sortedFriendsArray filteredArrayUsingPredicate:predicate];
if ([states count]>0) {
//---extract the relevant state from the states object---
NSDictionary *friend = [states objectAtIndex:indexPath.row];
long long fbid = [[friend objectForKey:#"id"]longLongValue];
NSString *name = [friend objectForKey:#"name"];
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%qi/picture?type=square",fbid];
NSURL *url = [NSURL URLWithString:urlString];
UILabel *eventNameLabel = (UILabel *) [cell viewWithTag:1];
eventNameLabel.text = name;
UIImageView *eventLogo = (UIImageView*) [cell viewWithTag:2];
eventLogo.image = [UIImage imageNamed:#"112-group.png"];
// eventLogo.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];;
}
return cell;
}
CURRENT didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSNumber *indexNumber = [NSNumber numberWithInt:indexPath.row];
NSDictionary *friend = [sortedFriendsArray objectAtIndex:indexPath.row];
long long fbid = [[friend objectForKey:#"id"]longLongValue];
NSNumber *fbidNum = [NSNumber numberWithLongLong:fbid];
if ([checkedCells objectForKey:indexNumber] != nil) {
[checkedCells removeObjectForKey:indexNumber];
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
[checkedCells setObject:fbidNum forKey:indexNumber];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
NSLog(#"Cell Pressed: %#",indexNumber);
NSLog(#"FBID: %lld",fbid);
NSLog(#"Array: %#",checkedCells);
}
It looks like you're only saving the checked cells by row, not by section and row. At minimum, don't you need to be testing the section as well as the row in this block of code?
if ([checkedCells objectForKey:[NSNumber numberWithInt:indexPath.row]] != nil) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
It's late, and I don't have my Mac handy to try this code, so maybe I'm missing something obvious. I'm not sure what you're talking about only returning zero ... is that indexPath.row?
EDIT:
To account for the section in your data array, I'd suggest storing the data as a dictionary of arrays, one dictionary entry keyed by each letter, with the inner array holding all of the entries starting with that letter. It's a little more complicated to retrieve the data, but it correctly accounts for the section.
I supposed you could create some kind of an offset to account for the number of entries in each section and then use that to index into a flat array, but that would be a lot harder to maintain, in my view. I think the dictionary of arrays is the way to go.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//NSLog(#"Array: %#",rows);
return [rows count];// AT THIS LINE
}
Program received signal: “EXC_BAD_ACCESS”
THANKS FOR THE REPLY
Actually I have attached it to the WebPage By NSUrl where I have made a PHP array and I have created a NSLOG where I am getting the Values in the array form but When It exceute the line return [rows count];. It gives error when I am writting statically return 2; then it execute. I am explaining to you what I am doing. I am initialising the NIb with
Name tableViewController=[[JsonTestViewController alloc] initWithNibName:#"JsonTestViewController" bundle:nil];
In JsonTestViewController.m
I have this code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//NSLog(#"Array: %#",rows);
return [rows 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:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure the cell.
NSDictionary *dict = [rows objectAtIndex: indexPath.row];
NSString *strlb1=[dict objectForKey:#"block"];
NSString *strlb2=[dict objectForKey:#"name"];
strlb1=[strlb1 stringByAppendingString:#" , "];
strlb1=[strlb1 stringByAppendingString:strlb2];
NSString *str1=#"FPS : ";
NSString *str2=[dict objectForKey:#"p_hours"];
NSString *strpinf;
if([str2 isEqualToString:#"FP"])
{
strpinf=#"Free Parking";
}
else if([str2 isEqualToString:#"12"])
{
strpinf=#"2 hours";
}
else if([str2 isEqualToString:#"14"])
{
strpinf=#"4 hours";
}
else if([str2 isEqualToString:#"MP"])
{
strpinf=#"Metered Parking";
}
str1=[str1 stringByAppendingString:strpinf];
cell.textLabel.text =strlb1;
cell.detailTextLabel.text = str1;
return cell;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"SITE URL"];
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:url];
NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSError *error = nil;
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
if (dict)
{
rows = [dict objectForKey:#"users"];
}
NSLog(#"Array: %#",rows);
[jsonreturn release];
}
- (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.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
can you give more info? This can be anything, but most likely, rows is pointing to memory where a valid array used to be. How did you create the rows array?
For example, your rows array or dictionary not longer pointing to valid memory if you created the rows array as an autoreleased object through a factory method in another method.
Here's another question that's pretty close to what you're describing:
EXC_BAD_ACCESS signal received
EDIT:
So looking at the code you provided, with these lines there are some possibilities:
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
if (dict) { rows = [dict objectForKey:#"users"]; }
the deserializeAsDictionary method can return either an autoreleased dictionary or NULL. so one possibility is that rows = NULL. when you try [rows count], your program will crash. Check and see what's in error, might give you some clues.
This will cause an error even when you explicitly return 2 for numberOfRowsInSection: because in cellForRowAtIndexPath:, you're still trying to access rows, even if it could possibly be NULL.
the other possibility lies in how you've defined rows. I'm guessing it's a property in your class. But where you have rows=[dict objectForKey:#"users"];, rows can point to nothing after the method's finished. Rows will still have the address of where [dict objectForKey:] was, but after the scope of the method, dict may be gone and all the data that comes with it.
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
under the KVC guidelines, you should expect dict to autorelease after the end of method.
and another possibility is, since i don't know the specifics of the JSON class you're using, is that when you release jsonreturn, you're also dealloc'ing all the data associated with it. So in effect, rows is pointing to nothing.
case in point, the error seems to be rooted in how you're setting/retaining/accessing rows.
try using the Build->Build&Analyze in xcode. it might give you some more hints. or throw in a bunch of NSLog(#"%d",[rows count]); all over. also try using the debugger. it'll give you a trace of method calls that lead up to [rows count] faulting.