Error on coredata viewcontrollers - objective-c

I have a Core Data stack in which there are two entities: 'Client' and 'Car'. Both are represented by tableViewControllers.
The first tableViewController fetches the list of clients and then once selected, the second displays a list of cars that client owns. Both are pushed onto a navigation controller. When I go 'back' from the second viewcontroller the program shows the firstviewcontroller successfully, waits a second or so then crashes. When I did a 'build and debug' the console gave this error:
Program received signal: “EXC_BAD_ACCESS”.
I dont understand it. Where should I look to find the error?
EDIT:I have included some code below to see if it is due to bad memory handling... I have deleted all commented out methods and as well as those not used before error crops up.
This is my ClientListViewController...
#implementation ClientListViewController
#synthesize clientsArray;
#synthesize coreDataModel;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
// Set the title
self.title=#"Clients";
[self populateTable];
}
-(void)populateTable {
[self setClientsArray:[coreDataModel retrieveClientList]];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (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 [clientsArray 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...
Client *client = (Client *)[clientsArray objectAtIndex:indexPath.row];
cell.textLabel.text = [client name];
return cell;
[client release];
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Create and push new view controller.
ClientCarsViewController *clientCarsViewController = [[ClientCarsViewController alloc] initWithNibName:#"ClientCarsViewController" bundle:nil];
//Pass the CoreDataModel to the view controller
clientCarsViewController.coreDataModel = coreDataModel;
// Pass the selected object to the new view controller
Client *client = (Client *)[clientsArray objectAtIndex:indexPath.row];
clientCarsViewController.client = client;
// Push the new viewController
[self.navigationController pushViewController:clientCarsViewController animated:YES];
// Release the objects
[clientCarsViewController release];
[client release];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
self.clientsArray = nil;
}
- (void)dealloc {
[clientsArray release];
[coreDataModel release];
[super dealloc];
}
#end
This is my ClientCarsViewController implementation...
#implementation ClientCarsViewController
#synthesize carsArray;
#synthesize coreDataModel;
#synthesize client;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = client.name;
// Get client's cars
NSSet *cars = client.cars;
// Import them into the carsArray
[self setCarsArray: [NSMutableArray arrayWithArray:[cars allObjects]]];
[cars release];
}
-(void)addCarToClient {
[coreDataModel addCarToClient:(Client *)client];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (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 [carsArray 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...
Car *car = (Car *)[carsArray objectAtIndex:indexPath.row];
cell.textLabel.text = [car carName];
return cell;
[car release];
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
self.carsArray = nil;
}
- (void)dealloc {
[self.client release];
[self.coreDataModel release];
[self.carsArray release];
[super dealloc];
}
#end

You are releasing objects you don't own. Have o look at Objective-C Memory Management Rules.
For example, when you obtain an object client like this:
Client *client = (Client *)[clientsArray objectAtIndex:indexPath.row];
You don't own it and should not release it.

Related

Adding tableview according to switch

I Have a tabbar with two items, one is a ViewController with a switch, the other is a Tableview, what i want to do is:
when the user hits the button the tableview will earn a new cell...
Codes:
viewclass.h:
#import <UIKit/UIKit.h>
#interface viewclass : UIViewController
#property (strong, nonatomic) IBOutlet UISwitch *myswitch;
#end
viewclass.m:
#import "viewclass.h"
#implementation viewclass
#synthesize myswitch;
- (void)viewDidUnload {
[self setMyswitch:nil];
[super viewDidUnload];
}
#end
tableviewclass.h:
#import <UIKit/UIKit.h>
#interface tableviewclass : UITableViewController{
NSMutableArray *list;
}
#end
tableviewclass.m:
#import "tableviewclass.h"
#import "viewclass.h"
#implementation tableviewclass
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
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
{
classedasrespostas *testswitch;
[super viewDidLoad];
list = [[NSMutableArray alloc] init];
if (testswitch.myswitch.on == YES) {
[list addObject:#"myobject"];
}
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (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 [lista count];
}
- (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...
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
This, classedasrespostas *testswitch;, does not create an object; it only declares a pointer that is going to hold the address of an object. Since you don't assign anything to it, there's nothing for it to act on when you get to if (testswitch.myswitch.on == YES) {.
Put NSLog(#"testswitch: %#", testswitch); before the if statement to see the problem.

How to push a table view AND be able to put data in the cells from a segue?

I have a first table view and a segue that pushes to another table view. I'm already able to push the second table view when the user touches a cell from the first table view, but I can't but data in the second table view. My second table view is using my custom controller which inherits from UITableViewController. I use the method "cellForRowAtIndexPath:(NSIndexPath *)indexPath" to put text in my cells, but the code never gets to that method. I don't understand what the problem is.
Here is my custom class:
#import "TableViewControllerTop.h"
#interface TableViewControllerTop ()
#end
#implementation TableViewControllerTop
#synthesize tableView;
#synthesize cells;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[self setTableView:nil];
[self setCells:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 6;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Top 50 list";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.textLabel.text = #"Test";
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"selected");
}
#end
Thanks for your help. I can post more code if necessary.
Looks like your code is returning 0 for number of sections. So therefore it thinks there is nothing to show.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 0;
}

How to Programmatically Create UITableView and Populate with NSArray in Xcode 4.2?

I have been struggling to understand the difference between Storyboards and coding in Objective-C. It appears you can create a UITableView by both dragging the object into your Storyboard, or coding in a new view within Objective-C.
The problem is that I want to keep my Storyboard as slim as possible. So I'm trying to build and populate a UITableView with an NSArray of 5 strings. My code will only run 1 row before returning a compiler error... I am going to scrap the whole project and start fresh.
I would be very grateful if somebody familiar with the new Xcode 4.2/iOS5/Storyboards can provide a reasonable solution for building the UITableView. I know this is such a basic task which is why it's so frustrating to begin with. I can get the Table View working, but I cannot seem to get an Array to dynamically fill and create #X number of rows...
Let me know if I can provide any more info. I've tried to be as straightforward as possible - just need to get a TableView working and populate with an Array :)
EDIT - here is my project source code you can download to check out where I'm at.
The reason it crashes is that in the storyboard you have to change the tableview to dynamic prototypes instead of static cells.
For some reason Static Cells is the default setting. Once you get the hang of the Storyboards it's great, especially when dealing with tableviews. Your initial View is set up as the NavigationController which has your MasterviewController as the RootViewController, so it's being loaded as the firstView. Click on the TableView in the MainStoryboard and change the Cels to Dynamic Prototypes or it will use the static ones that you create right in the storyboard. You can make custom cells right on the tableview in the storyboard. One more thing to note is the re-use identifier has to be set to the same name in the storyboard and the TableViewController.
You can also just up the count of static cells to the number you want if you know it will always be the same.
Here's a trivial sample with subclassing UITableViewController populated with an NSArray (NSMutableArray) from my sample code. It doesn't use story boards but you said that's OK in your comment. Hopefully my sample code helps you.
Header:
#interface MainTableViewController : UITableViewController
{
NSMutableArray *_items;
}
#end
Implementation:
#implementation MainTableViewController
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Lifetime
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
// datastore
_items = [[NSMutableArray alloc] init];
for (int index=0; index < 5; index++)
{
[_items addObject:[NSString stringWithFormat:#"item #%d", index]];
}
}
return self;
}
- (void)dealloc
{
[_items release];
[super dealloc];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Table View DataSource
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// a typical table has one section
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// number of rows
return [_items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// NSIndexPath contains an array of indexes. For UITableView:
// indexAtPosition:0 is the section number
// indexAtPosition:1 is the row number
// create an identifier for this type of cell
static NSString *CellIdentifier = #"Cell";
// get a cell of this type from the re-use queue or create one
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *title = [_items objectAtIndex:[indexPath indexAtPosition:1]];
[[cell textLabel] setText:title];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source
NSLog(#"delete section: %d rol: %d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]);
[_items removeObjectAtIndex:[indexPath indexAtPosition:1]];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert)
{
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
NSLog(#"insert section: %d rol: %d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]);
}
}
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
NSString *fromItem = [_items objectAtIndex:[fromIndexPath indexAtPosition:1]];
[_items removeObjectAtIndex:[fromIndexPath indexAtPosition:1]];
[_items insertObject:fromItem atIndex:[toIndexPath indexAtPosition:1]];
}
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark UITableViewDelegate
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"selected section: %d rol: %d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]);
// get the selected cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
// navigate to detail
DetailedTableViewController *detailedView = [[DetailedTableViewController alloc] init];
[[self navigationController] pushViewController:detailedView animated:YES];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark View lifecycle
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
[[self navigationItem] setRightBarButtonItem: [self editButtonItem]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

NSFetchedResultsController Help

My table view is showing nothing (even though there is data), and when I switch back to it from a tab bar I get an error:
2011-06-28 11:25:20.043 Paparazzi[7773:207] -[__NSCFArray sections]: unrecognized selector sent to instance 0x592d2d0
2011-06-28 11:25:20.048 Paparazzi[7773:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray sections]: unrecognized selector sent to instance 0x592d2d0'
What am I doing wrong?
You can get the full code at:
https://github.com/blasto333/Paparazzi
Header
#interface PersonListViewController : UITableViewController {
NSFetchedResultsController *fetchResultsController;
}
#end
Implementation
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
fetchResultsController = [[FlickrFetcher sharedInstance] fetchedResultsControllerForEntity:#"Person" withPredicate:nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[fetchResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchResultsController sections] objectAtIndex:section];
return [sectionInfo 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] autorelease];
}
// Configure the cell...
Person *person = [fetchResultsController objectAtIndexPath:indexPath];
[cell.textLabel setText:person.name];
return cell;
}
You need to retain the fetchResultsController because it's being released as soon as it is created. The method fetchedResultsControllerForEntity:withPredicate returns an autoreleased object. Change the line to read:
fetchResultsController = [[[FlickrFetcher sharedInstance] fetchedResultsControllerForEntity:#"Person" withPredicate:nil] retain];
Intense memory management on iOS and Mac OS is going to be a thing of the past soon enough though. If you're a paying ADC member, go check out some of the beta releases of Xcode and test drive the automatic reference counting stuff. I've been using it for a few weeks and it's been great.
EDIT: You're not getting any rows to show up because your fetchResultsController doesn't have any data in it. The method numberOfSectionsInTableView: is returning zero, so none of your other methods for the TableViewDataSource protocol are even being called.

typical UITableView unrecognized selector sent to instance

I'm having this "tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance" error, I'm almost sure is some kind of memory management issue but right now I'm pretty much tired of having to find the bug.
The TableView displays the cells well as long as you don't scroll down, if you do..
app crashes.
The only property I use is called "places", I've already checked if I didn't miss a "self.".
so.. here's my code:
#import "PlacesViewController.h"
#import "FlickrFetcher.h"
#import "SinglePlaceViewController.h"
#implementation PlacesViewController
#synthesize places;
- (NSArray *)places
{
if (!places) {
NSSortDescriptor *content = [[NSSortDescriptor alloc] initWithKey:#"_content" ascending:YES];
NSArray *unsortedPlaces = [FlickrFetcher topPlaces];
places = [unsortedPlaces sortedArrayUsingDescriptors:[NSArray arrayWithObjects: content, nil]];
}
return places;
}
#pragma mark -
#pragma mark Initialization
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Top Places";
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (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 self.places.count;
}
- (NSDictionary *)placeAtIndexPath:(NSIndexPath *)indexPath
{
return [self.places objectAtIndex:indexPath.row];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"PlacesTableViewCell";
NSLog(#"%#", [FlickrFetcher topPlaces]);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSString *location = [[self placeAtIndexPath:indexPath] objectForKey:#"_content"];
NSArray *splitLocation = [location componentsSeparatedByString:#", "];
cell.textLabel.text = [splitLocation objectAtIndex:0];
if (splitLocation.count == 2)
cell.detailTextLabel.text = [splitLocation objectAtIndex:1];
if (splitLocation.count == 3)
cell.detailTextLabel.text = [[[splitLocation objectAtIndex:1] stringByAppendingString:#","] stringByAppendingString:[splitLocation objectAtIndex:2]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
SinglePlaceViewController *spvc = [[SinglePlaceViewController alloc] init];
// Pass the selected object to the new view controller.
spvc.placeId = [[self placeAtIndexPath:indexPath] objectForKey:#"place_id"];
[self.navigationController pushViewController:spvc animated:YES];
[spvc release];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[places release];
[super dealloc];
}
#end
Thank You very much for your help and I'm really sorry for making you all guys do a bit of work for me.
You didn't provide much info about the error so i can only guess:
The error indicates that the object that get the message cellForRowAtIndexPath: don't actually have this method implemented.
But since you DID implemented it, the only reason i can think of is that you are messing with your tableView's "dataSource" property and changing it to something you shouldn't.
Make sure that the dataSource is your PlacecViewController.
From what it looks like to me, the getter method for your places property is not retaining the value it returns. You are setting it to an autoreleased instance of NSArray you're getting from the sortedArray method. I'm willing to bet it's being released after it displays your initial tableview cells.