Loading NSArray UITableViewController - objective-c

I have a tabbed view controller and I put a table view in it but when I run the program I got this EXC_BAD_ACCESS signal.
The array does not get loaded and produces this error.
Here is my code:
ContactsViewController.h
#import <UIKit/UIKit.h>
#interface ContactsViewController : UITableViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic ,retain) NSArray *items;
#end
ContactsViewController.m
#import "ContactsViewController.h"
#interface ContactsViewController ()
#end
#implementation ContactsViewController
#synthesize items;
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
items = [[NSArray alloc] initWithObjects:#"item1", #"item2", "item3", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
return cell;
}
#end

The problem with your code lies (as the debugger tells you) in the following line:
items = [[NSArray alloc] initWithObjects:#"item1", #"item2", "item3", nil];
Take a closer look at "item3". There is no # sign in front of it so it is not an NSString object but a plain old C string. You can only put objects into an NSArray.
Change it to
items = [[NSArray alloc] initWithObjects:#"item1", #"item2", #"item3", nil];
or even simpler
item = #[#"item1", #"item2", #"item3"];

Without the rest of the code it's not possible to say for sure what the problem is, but you should access the variable through the property in the following way.
self.items = ...
Also consider using the shorthand array notation, like this.
self.items = #[#"Item 1", #"Item 2", #"Item 3"];
IMO: The only time you should use variables directly is in an overriden property accessory.
Also note that if you do want to use the variable directly you should change the synthesize command to the following #synthesize items = variableName; This puts a name, variableName on the underlying variable used in the property. You can then access the variable without going through the property.

Related

How to load array into a UITableView, not TableViewController

I am trying to take an array that I loaded from another viewer and put it into a UITableView, not a TableViewController. I don't know how I would do this. Right now I have this code:
CRHCommentSection.m
#import "CRHCommentSection.h"
#import "CRHViewControllerScript.h"
#interface CRHCommentSection ()
#end
#implementation CRHCommentSection
#synthesize observationTable;
NSArray *myArray;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
myArray = [CRHViewControllerScript theArray];
NSLog(#"%#", myArray);
//NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:1]];
//[observationTable insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
NSLog(#" in method 1");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#" in method 2");
// Return the number of rows in the section.
return [myArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#" in method 3");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
return cell;
}
CRHCommentSection.h
#import <UIKit/UIKit.h>
#interface CRHCommentSection : UIViewController
#property (weak, nonatomic) IBOutlet UITableView *observationTable;
#end
Since you have posted this same example code more than once, Ill give you the way to do this without using statics. And Yes you do need to set the collection (array) on the view controller not the UITableView as the tableView uses the controller as a datasource.
Lets say you had a UITableView that displayed search results... And you launch this view controller from either some other view or from the application delegate like so..
In your viewController (yours is CRHCommentSection) define a property for the array you are going to populate the table with.
#property (nonatomic,retain, setter=setSearchResults:) NSArray *searchResults; //use your array name here
//BTW please dont call it ARRAY..its confusing.
Also in your commentsController (which would be a better name that what you have) add the setter for
the array
-(void) setSearchResults:(NSArray *)searchResults
{
//in case we loaded this view with results previously release the previous results
if ( _searchResults )
{
[_searchResults release];
}
_searchResults = [searchResults retain];
[_tableView reloadData];
}
When you instantiate the new view controller with the UITableView in it - set the "array",
in your case comments in my case searchResults
_searchResultsViewController = [[SearchResultsViewController alloc] initWithNibName:#"SearchResultsViewController" bundle:nil];
//now set the array on the controller
_searchResultsViewController.searchResults = mySearchResults; //(your array)
Thats a simple way to communicate the array for the table view when you instantiate a view controller.
Also the naming conventions will help you clear things up
If you have a view controller for comments it should be
CommentsViewController
And the array if it contains comments should be called comments - for readability.
Cheers.
As for the rest of the boilerplate setting the datasource and delegate and cellForRow etc,
you got that advice on the last go around so I wont repeat it here.
#bigkm had a good point
#interface SearchResultsViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
Your view controller has to be defined properly as above with the protocols.
You need to set the data source
[self setDataSource:self];
And also add the protocol to your interface.
<UITableViewDataSource>

My second level detail controller is not showing the initWithObjects in my array in the viewDidLoad method

I am creating a Two Level table view. And the second view is supposed to have the list of the movies I have listed below in my viewDidLoad method, but it is not showing.(You can see my screen shots attached)Does anyone know which file where I can look to see why it is not showing? The code below is from my DisclosureButtonController.m file which is to display this information after I hit the Disclosure Buttons instance on the First Level screen.
Regards,
#import "LWWDisclosureButtonController.h"
#import "LWWAppDelegate.h"
#import "LWWDisclosureDetailController.h"
#interface LWWDisclosureButtonController ()
#property (strong, nonatomic) LWWDisclosureDetailController *childController;
#end
#implementation LWWDisclosureButtonController
#synthesize list;
#synthesize childController;
//- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
//{
// self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//if (self) {
// Custom initialization
//}
//return self;
//}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *array = [[NSArray alloc] initWithObjects:#"Toy Story", #"A Bug's Life", #"Toy Story 2", #"Monsters, Inc.", #"Finding Nemo", #"The Incredibles", #"Cars", #"Ratatouille", #"WALL-E", #"Up", #"Toy Story 3", #"Cars 2", #"Brave", nil];
self.list = array;
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.list = nil;
self.childController = nil;
// Release any retained subviews of the main view.
}
#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];//
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString * DisclosureButtonCellIdentifier = #"DisclosureButtonCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DisclosureButtonCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:DisclosureButtonCellIdentifier];
}
NSUInteger row = [indexPath row];
NSString *rowString = [list objectAtIndex:row];
cell.textLabel.text = rowString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hey, boss do you see the disclosure button?" message:#"If you're trying to drill down, touch that instead mate!" delegate:nil cancelButtonTitle:#"Won't happen again" otherButtonTitles:nil];
[alert show];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *)indexPath
{
if (childController == nil)
{
childController = [[LWWDisclosureDetailController alloc]initWithNibName:#"LWWDisclosureDetail" bundle:nil];
}
childController.title = #"Disclosure Button Pressed";
NSUInteger row = [indexPath row];
NSString *selectedMovie = [list objectAtIndex:row];
NSString *detailMessage = [[NSString alloc]initWithFormat:#"You pressed the disclosure button for %#.", selectedMovie];
childController.message = detailMessage;
childController.title = selectedMovie;
[self.navigationController pushViewController:childController animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Why not start the array with the VC instead of after the VC loads? Try overriding the init method.
- (id) init {
if((self == [super init])) {
//load your array here and set
}
return self;
}
That way, on older devices, you don't have to wait after the view loads to see the array. But, however, this is my preference. I love to override init methods and create my own.
Also, for some weird reason on my SDK, I have to use NSMutableArray instead of NSArray or it won't work. Maybe you have the same issue?
Also, I've noticed NSString *selectedMovie. Instead of using just "row", use the getter indexPath.row.
Hope these suggestions helped!
Call:
[self.tableView reloadData]; (put in place of self.tableView the var or property connected to the tableView)
after the:
self.list = array;
code line in the viewDidLoad method
and put a
NSLog(#"number of rows: %d", [self.list count]);
in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];//
}
to check if it is not zero.

how can solve the “SIGKILL” error in UITableView (when built the table view using Storyboard)

I'm the beginner of IOS development.
I try to use the Storyboard to produced a UITableView, But when I run this App, it appear the "Program received signal: 'the SIGKILL' ".
I built a table using Storyboard (without ARC), but there is a problem during the runtime .
Here given in the code:
#import "MainTableViewController.h"
#interface MainTableViewController ()
#property (strong, nonatomic) NSMutableArray *myArray;
#end
#implementation MainTableViewController
#synthesize myArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
myArray = [NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.myArray = 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 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArray 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] autorelease];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row]; // 这儿出现异常 Program received signal: “SIGKILL”
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ }
#end
I moving up and down on the screen, and then occurs this runtime error.
I enabled the Zombie function. I found the "myArray" is NSZombie Objects,
And then the debug continue,
and I found another error "EXC_BAD_ACCESS" at the same line.
cell.textLabel.text = [myArray objectAtIndex: indexPath.row];
The myArray still is a zombie object.
How do you solve it?
Thank you! !
You have created myArray using the arrayWithObjects: method. This method returns an object that you do not own. Since you don't own it, the object might be deallocated (turn into a zombie) the next time the program goes through its run loop. In fact, that is exactly what is happening.
If you want the object to stay around, you have to become an owner of it. You do that by retaining it. There are three ways you can retain it. You can explicitly send it a retain message:
myArray = [[NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil] retain];
or you can use the property setter method:
[self setMyArray:[NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil]];
You can use dot-syntax, which uses the property setter method “under the covers”:
self.myArray = [NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil];
The property setter method (generated by the compiler) automatically retains the object.
You put the reference directly into your instance variable instead of using the setter method. It is easy to make this mistake. The compiler can help you catch this mistake if you synthesize your property differently:
#synthesize myArray = _myArray;
If you do that, the property is stored in an instance variable named _myArray, instead of an instance variable named myArray. So you have to explicitly use the _ in front of the name to access the instance variable directly:
// COMPILE-TIME ERROR!
myArray = [NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil];
// Compiles ok
_myArray = [[NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil] retain];
// Also compiles ok
self.myArray = [NSMutableArray arrayWithObjects:#"apple",#"orange",#"bananas", nil];
If you use the _ prefix on all of your instance variables, then you know that whenever you are setting something that starts with an _, you need to worry about retaining the new value and releasing the old value.
The third way you can retain the object, and the best, is to turn on ARC (Automatic Reference Counting) for your project. Then you don't have to worry about retaining and releasing objects. The compiler will automatically retain and release the object at the right times, even if you use the instance variable directly.
If you decide not to use ARC, then you need to study Cocoa Core Competencies: “Memory Management”, until you understand the rules.

Failed to call designated initializer on NSManagedObject class

Another newbie question, just when I thought I was beginning to get a very
small handle on ios programming. Ugh! I'm following a tutoria from the
appcodeblog.com where I'm building a simple tab bar application utilizing
core data to enter, display, and search vacation destinations. I've worked
through the tutorial and have a working app, but I notice when I select the
"Show Destinations" tab I get the following error. The app seems to continue
working, but the error is logged to the console. I'm trying to debug the
issue and understand exactly what is happening, but I just don't quite
understand what is wrong. I "think" I have an issue with my
ShowDestinations.xib file where I've incorrectly hooked up my objects within
the xib. Any help is MUCH appreciated. Thanks in advance for your help and
time.
Here's the error, "CoreDataTabBarTutorial[1262:207] Failed to call designated
initializer on NSManagedObject class 'Destination'.
I'm not sure what code to provide so I've started out by showing my header
and implementation files ShowDistinationsViewController.h and
ShowDestinationsViewController.m
ShowDistinationsViewController.h
#import <UIKit/UIKit.h>
#interface SearchDestinationsViewController : UIViewController {
UISearchBar *destinationSearchBar;
UITableView *searchTableView;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
NSArray *fetchedObjects;
}
#property (nonatomic, retain) IBOutlet UISearchBar *destinationSearchBar;
#property (nonatomic, retain) IBOutlet UITableView *searchTableView;
#property (nonatomic, retain) IBOutlet NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, retain) IBOutlet NSManagedObjectContext *managedObjectContext;
#end
ShowDestinationsViewController.m
#import "ShowDestinationsViewController.h"
#import "Destination.h"
#implementation ShowDestinationsViewController
#synthesize destinationsTableView;
#synthesize destinationsArray;
#synthesize fetchedResultsController;
#synthesize managedObjectContext;
// Not sure where the following code came from so I commented it out!!! It didn't seem to break anything when I commented it out
//- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
//{
// self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
// if (self) {
// // Custom initialization
// }
// return self;
//}
- (void)dealloc
{
[destinationsArray release];
[destinationsTableView release];
[super dealloc];
}
- (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
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
- (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);
}
#pragma mark -
#pragma Data Fetch from Core Data
- (void) viewWillAppear:(BOOL)animated
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Destination" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil)
{
// Handle the error.
NSLog(#"mutableFetchResults == nil");
}
[self setDestinationsArray:mutableFetchResults];
[request release];
[destinationsTableView reloadData];
}
#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 [destinationsArray 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...
Destination *destination = [[Destination alloc] init];
destination = (Destination *)[destinationsArray objectAtIndex:indexPath.row];
cell.textLabel.text = destination.name;
[destination release];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#end
The problem seems to lie in
Destination *destination = [[Destination alloc] init];
destination = (Destination *)[destinationsArray objectAtIndex:indexPath.row];
[destination release];
The first line is unnecessary: In Objective-C, Destination* is a pointer to the object, not the real object. The Destination object you want is presumably already in the array. So you don't have to create an object to point to, in the line [[Destination alloc] init], which is gone immediately at the next line. What's going on was
[[Destination alloc] init] creates an object a, destination points to a. a is retained by you.
(Destination *)[destinationsArray objectAtIndex:indexPath.row] gives you another object b, which is not retained by you. destination now points to b. No one holds a any longer.
release is sent to the object pointed to by destination, i.e., to b. This is against the retain-release rule; you should release a, not b!
So, instead, just do
Destination *destination = (Destination *)[destinationsArray objectAtIndex:indexPath.row];
without the release part.
As an advice: always run Analyze (which is available below the Build menu) when you build your project. The analyzer is designed to catch common types of errors, including yours. Correct your code so that all the analyzer warnings go away; you should always regard the analyzer warning as an error on your part.

Why is my tab bar controller crashing?

I'm trying to create a iPhone app that uses a tab bar controller. The first tab works fine.
However, when I click the second tab in the tab bar the whole app crashes. I am trying to implement a table view in the second tab.What could be causing the crash?
Here is my code:
SecondViewController.h
#import <UIKit/UIKit.h>
#class Person;
#interface SecondViewController : UIViewController<UITableViewDelegate, UITableViewDataSource >{
UITableView *tableView;
NSArray *persons;
}
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic,retain ) NSArray *persons;
-(void)initPersons:(NSArray *) array;
#end
SecondViewController.m
#import "SecondViewController.h"
#import "Person.h"
#implementation SecondViewController
#synthesize tableView;
#synthesize persons;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
- (id)init {
if (self = [super initWithNibName:#"SecondViewController" bundle:nil]) {
//self.title = #"Slot";
UIImage* anImage = [UIImage imageNamed:#"cherry.png"];
UITabBarItem* theItem = [[UITabBarItem alloc] initWithTitle:#"table" image:anImage tag:0];
self.tabBarItem = theItem;
[theItem release];
}
return self;
}
-(void)initPersons:(NSArray *) array{
int size = [array count];
int i = 0;
NSMutableArray *aPersons = [NSMutableArray array];
while (i < size) {
Person *person = [[Person alloc]init];
NSString * name =[array objectAtIndex:i];
NSArray *chunks =[name componentsSeparatedByString: #" "];
person.firstName = [chunks objectAtIndex:0];
person.lastName = [chunks objectAtIndex:[chunks count]-1];
[aPersons addObject:person];
[person release];
i++;
}
self.persons=aPersons;
[aPersons release];
}
-(NSArray *)sortArray {
NSSortDescriptor *lastNameDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"lastName"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSSortDescriptor *firstNameDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"firstName"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObjects:lastNameDescriptor,
firstNameDescriptor, nil];
return [persons sortedArrayUsingDescriptors:sortDescriptors];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc] initWithObjects:
#"Amin Alrusayni", #"Berksan Ates",
#"Becca Bedell", #"Joseph Carioti",
#"Christopher Conry", #"Jeremy Dobbins", #"Timothy Fox",
#"Eric Green", #"Timothy Gruscinski", #"Daniel Gur",
#"Yousef Guzaiz", #"Tyler Herzog", #"Alicia Johnson", #"Scott Kazakis",
#"Nathan Kidwell", #"Dakota Kincer", #"Scott Moore",
#"Sean Reber", #"Michael Romeo", #"Alexander Shibble",
#"Joshua Shipley", #"Mitchell Slemc", #"Thomas Smith",
#"Christopher Wagner", #"Corey Zachrich", #"Ahmed Alalawi",
#"Abdullah Alqahtani", #"Daniel Angelis", #"Brian Bartman",
#"William Haverstock", #"Hui Hong", #"Rong Li",
#"Amitkumar Mali", #"Christian Newman", nil];
[self initPersons:array];
NSArray *sortedArray = [self sortArray];
for (Person *person in sortedArray)
{
NSString *fullName = [[person.firstName stringByAppendingString:#" "] stringByAppendingString:person.lastName];
NSLog(#"%#",fullName);
NSLog(#" ");
}
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
//commented out this function
/*
- (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 {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[tableView dealloc];
[super dealloc];
}
#pragma mark -
#pragma mark TableView DataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.persons count];
}
/*- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [persons objectAtIndex:row];
return cell;
}*/
#end
It would be easier to help if you post your code using markdown formatting as Moshe commented. I did notice a few things with a quick scan. I also can't tell from this what you have created in interface builder and if the UITabBarController and all outlets are properly configured. You may have other things going on besides the following but here's a start.
Make sure you release anything you retain. for example, in viewDidLoad you allocate array and never release it.
Similarly, don't release things you haven't retained. In initPersons you create the mutable array aPersons using an array constructor that returns an autoreleased object. You then have [aPersons release]. This will cause a crash b/c you are releasing an object you haven't retained.
Clean up properly in viewDidUnload and dealloc. In both of these you need to release tableView. In dealloc you have [tableView dealloc]. That should be [tableView release]
Your data source creation is overly complicated but I do see a clear problem. You are setting self.persons in initPersons which is fine. You then sort the array and store it in sortedArray. Assuming your intent is to keep the array sorted, you are currently discarding the sorted array. self.persons remains the unsorted version. While this is not a crash, I doubt this was your intent.
You need to implement tableView:cellForRowAtIndexPath: This will absolutely cause a crash if missing. That's assuming you have the tableView delegate and dataSource configured correctly. You should add the protocols UITableViewDataSource and UITableViewDelegate to the interface definition for SecondViewController so you'll get the proper compiler warnings regarding implementing required protocol methods.
– tableView:cellForRowAtIndexPath: is required method of UITableviewDatasource protocol.so enable it.be happy
if u dont want any implementaion in it then just leave it with blank definition.
{
return cell;
}