NULL elements in NSMutableArray - objective-c

I have a problem...
IN my MuttableArray have N element, but all elements is null
.h
#interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {
NSMutableArray *listProjectPost;
}
#property (retain,nonatomic) NSMutableArray *listProjectPost;
.m
#implementation ViewController
#synthesize listProjectPost;
-(void)dealloc
{
[self.listProjectPost release];
[super dealloc];
}
-(void)viewWillAppear:(BOOL)animated{
self.listProjectPost = [NSMutableArray array];
// loop code
// current element
currentNews *dop = [[currentNews alloc] init];
[self.listProjectPost addObject:[dop createElement:node]];
[dop release];
}
in
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
currentNews *dop = [self.listProjectPost objectAtIndex:indexPath.row];
cell.textLabel.text = [dop getTitle];
...
}
all ok in top view (view when creating)
but next index i have error - EXC_BAD_ACCESS
sorry for my english

If you need to store a null value in an Objective-C array, use [NSNull null]. You should check [drop createElement:node] to see if it is nil before adding it to your array.

Related

Loading NSArray UITableViewController

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.

Create an array of custom Object to fill it and take his content to fill a UITableView

I have a Class called Product that contains some propeties, I wanna make that my class will be the base for an list of Product called Products. And this list can access in a UITableView to fill it with the content of Products.
Also, the content of each product will be filled by a web service.
My code is:
#interface Product : NSObject
{
int identifier;
NSString* title;
NSString* quantity;
float price;
UIImage* image;
}
#property (nonatomic, assign) int identifier;
#property (nonatomic, retain) NSString* title;
#property (nonatomic, retain) NSString* quantity;
#property (nonatomic, assign) float price;
#property (nonatomic, retain) UIImage *image;
-(id)initWithProduct:(int) identifier withTitle:(NSString*)title numberUses:(NSString*)uses withPrice:(float)price withImage:(UIImage*)image;
#end
With his .m
#implementation Product
#synthesize identifier = _identifier;
#synthesize title = _title;
#synthesize price = _price;
#synthesize quantity = _quantity;
#synthesize image = _image;
- (void)dealloc {
NSLog(#"article dealloc \n");
[self.title release];
[self.quantity release];
[self.image release];
[super dealloc];
}
- (id)init {
self = [super init];
if(self) {
self.title = [[[NSMutableString alloc] init] autorelease];
self.identifier = 0;
self.price = 45.0;
self.quantity = [[[NSMutableString alloc] init] autorelease];
self.image = [[[UIImage alloc] init] autorelease];
}
return self;
}
-(id)initWithProduct:(int) inIdentifier withTitle:(NSString*)inTitle numberUses:(NSString*)inQuantity withPrice:(float)inPrice withImage:(UIImage*)inImage
{
self = [super init];
if (self) {
if (title!= nil) {
self.title = inTitle;
}
if (quantity!= nil) {
self.quantity = inTitle;
}
if (image!= nil) {
self.title = inTitle;
}
self.price = inPrice;
self.identifier = inIdentifier;
}
return self;
}
#end
My UITableView header is:
#interface TableView : UIViewController
< UITableViewDataSource
, UITableViewDelegate
>{
NSMutableArray *products;
}
in the m. I have:
EDIT
Now the Title of my cell is shows as (null)
- (void)viewDidLoad
{
[super viewDidLoad];
products = [[NSMutableArray alloc] init];
[products addObject:[[Product alloc] initWithProduct:1 withTitle:#"df" numberUses:#"dsf" withPrice:12.3 withImage:[UIImage imageNamed:#"btn_invite"]]];
[products addObject:[[Product alloc] initWithProduct:1 withTitle:#"2" numberUses:#"dsf" withPrice:12.3 withImage:[UIImage imageNamed:#"btn_invite"]]];
[products addObject:[[Product alloc] initWithProduct:1 withTitle:#"4" numberUses:#"dsf" withPrice:12.3 withImage:[UIImage imageNamed:#"btn_invite"]]];
[products addObject:[[Product alloc] initWithProduct:1 withTitle:#"4" numberUses:#"dsf" withPrice:12.3 withImage:[UIImage imageNamed:#"btn_invite"]]];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Controller *cell = (Controller*)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSString* nameNib = UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM() ? #"Controller" : #"ControllerIph";
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nameNib owner:self options:nil];
cell = [nib objectAtIndex:0];
}
Product* obj = [products objectAtIndex:indexPath.row];
cell.title.text = [NSString stringWithFormat:#"%#", obj.title];
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4;
}
Thanks in advance!
Not an answer to your question, but a few comments regarding your code:
You have 4 memory leaks when you add the 4 new instances of Product to your array. The array retains the objects you add to it, so you should autorelease the Product instances when you add them.
In dealloc you should say self.title = nil instead of [self.title release]. Although your version works, it leaves you with instance variables that contain references to deallocated objects (= dangling pointers). Because this happens in dealloc and the Product object is going away soon, it won't hurt you now, but you will get bitten at some point in the future if you keep to this style.
You don't need to declare the instance variables, and you don't need to synthesize the properties. The compiler does all this for you.
In initWithProduct you must not check things like if (title!= nil) - just say self.title = inTitle straightaway. After all, initWithProduct is an initializer just like init, so title cannot contain anything at this point.
Hope this helps.
EDIT
Actually, the last point is probably why you see "(null)" for the title of your cells. Your check if (title!= nil) is never true because the instance variable title is nil during the initializer, so the assignment self.title = inTitle never happens.
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath you do not initialize cells for your TableView. Add the below code to this method before the code that you already have
static NSString *CellIdentifier = #"Cell Identifier";
UITableViewCell *cell;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
and make sure you return cell; at the end of that method
Also make sure you implement the rest of the necessary TableView delegate methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

Add NSTableView data to NSPopUpButton items

I have a NSTableView where items can be added and deleted. Once items have been added to the table, I would like those items to also show as items for an NSPopUpButton. I tried the addItemsWithTitles: method but it gives me an error.
#import "TableController.h"
#import "Favorites.h"
#interface TableController ()
#property NSMutableArray *array;
#property (weak) IBOutlet NSTableView *tableView;
#property (weak) IBOutlet NSPopUpButton *popButton;
#end
#implementation TableController
- (id)init {
self = [super init];
if (self) {
_array = [[NSMutableArray alloc] init];
}
return self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [_array count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Favorites *fav = [_array objectAtIndex:row];
NSString *ident = [tableColumn identifier];
return [fav valueForKey:ident];
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Favorites *fav = [_array objectAtIndex:row];
NSString *ident = [tableColumn identifier];
[fav setValue:object forKey:ident];
}
- (IBAction)add:(id)sender {
[_array addObject:[[Favorites alloc] init]];
[_tableView reloadData];
[_popButton addItemsWithTitles:_array];
}
-(IBAction)delete:(id)sender {
NSInteger row = [_tableView selectedRow];
[_tableView abortEditing];
if (row != -1) {
[_array removeObjectAtIndex:row];
}
[_tableView reloadData];
}
#end
So I tried logging the objectAtIndex:0 for the array and didn't get a string but received some numbers instead:
Array string is <Favorites: 0x10013e820>
And also for reference my Favorites class is
#import "Favorites.h"
#interface Favorites ()
#property (copy) NSString *location;
#end
#implementation Favorites
- (id)init {
self = [super init];
if (self) {
_location = #"City, State or ZIP";
}
return self;
}
#end
Your array has instances of your class, Favorites, and in your addItemsWithTiles: method you are adding those instances, not some string property of those instances, which is what I presume you want. If you use [_array valueForKey:#"whateverKeyHasYourStrings"] as the argument to addItemsWithTitles: instead of just _array, I think it will work ok.

IOS loading a tableview with data

I'm fairly new to iOS and have much more to learn, and hope you guys can guide me from my mistake.
I've recently learned passing data from TableView to DetailView, and thought, why not the other way around. I also start building a StopWatch app, and felt that a log function would be very useful.
With that said, I'm currently building a stopwatch app that works as a timer and have a high score log function. It goes from View(stopwatch) to tableView(log board) I'm using a NSMutableArray as a temp storage to hold the information as they should be lost when the app start/close. Unfortunately, it seem that by following and changing variable here and there, i got myself confuse and stuck now.
Thanks for the suggestion and help you guys gave and thanks #Abizern for giving me tips. Manage to solve all the problem. Shall leave the code here incase anyone in the future do similar things to this.
TimerViewController.h
#import <UIKit/UIKit.h>
#import "SampleData.h"
#import "SampleDataDAO.h"
#import "HighScoreTableViewController.h"
#interface TimerViewController : UIViewController
{
NSTimer *stopWatchTimer; // Store the timer that fires after a certain time
NSDate *startDate; // Stores the date of the click on the start button
}
#property(nonatomic, strong) SampleDataDAO *daoDS;
#property(nonatomic, strong) NSMutableArray *ds;
#property (retain, nonatomic) IBOutlet UILabel *stopWatchLabel;
#property (weak, nonatomic) IBOutlet UIButton *onStartPressed;
#property (weak, nonatomic) IBOutlet UIButton *onStopPressed;
#property (weak, nonatomic) IBOutlet UIButton *onLogPressed;
#property (weak, nonatomic) IBOutlet UIButton *onHighscorePressed;
- (IBAction)onStartPressed:(id)sender;
- (IBAction)onStopPressed:(id)sender;
- (IBAction)onLogPressed:(id)sender;
- (IBAction)onHighscorePressed:(id)sender;
#end
TimerViewController.m
#import "TimerViewController.h"
#interface TimerViewController ()
#end
#implementation TimerViewController
#synthesize stopWatchLabel;
#synthesize onStartPressed;
#synthesize onStopPressed;
#synthesize onLogPressed;
#synthesize onHighscorePressed;
#synthesize ds,daoDS;
- (void)viewDidLoad
{
[super viewDidLoad];
daoDS = [[SampleDataDAO alloc] init];
self.ds = daoDS.PopulateDataSource;
onStopPressed.enabled=false;
}
- (void)viewDidUnload
{
[self setStopWatchLabel:nil];
[self setOnStartPressed:nil];
[self setOnLogPressed:nil];
[self setOnStopPressed:nil];
[self setOnHighscorePressed:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
HighScoreTableViewController *detailViewController = [segue destinationViewController];
detailViewController.arrayOfSampleData = self.ds;
}
}
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.S"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLabel.text = timeString;
}
- (IBAction)onStartPressed:(id)sender {
startDate = [NSDate date];
// Create the stop watch timer that fires every 10 ms
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
onStartPressed.enabled=false;
onStopPressed.enabled=true;
}
- (IBAction)onStopPressed:(id)sender {
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[self updateTimer];
onStartPressed.enabled=true;
}
- (IBAction)onLogPressed:(id)sender {
NSString * timeCaptured = stopWatchLabel.text;
static NSInteger i = 1 ;
SampleData* mydata = [[SampleData alloc]init];
mydata.clueName=[NSString stringWithFormat:#"clue %d",i++ ];
mydata.timeLog = timeCaptured;
[self.ds addObject:mydata];
NSLog(#"%#",mydata.clueName);
NSLog(#"time %#", mydata.timeLog);
NSLog(#"%d",[self.ds count]);
mydata=nil;
}
- (IBAction)onHighscorePressed:(id)sender {
NSLog(#"Proceeding to HighScore");
}
#end
HighScoreTableView.h
#import <UIKit/UIKit.h>
#import "SampleData.h"
#import "SampleDataDAO.h"
#import "TimerViewController.h"
#interface HighScoreTableViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *arrayOfSampleData;
#property (nonatomic, strong) SampleData * highscoreData;
#end
HighScoreTableView.m
#import "HighScoreTableViewController.h"
#interface HighScoreTableViewController ()
#end
#implementation HighScoreTableViewController
#synthesize highscoreData;
#synthesize arrayOfSampleData;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
highscoreData = [[SampleData alloc]init];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[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
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.arrayOfSampleData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"highscoreCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//highscoreData = [self.arrayOfSampleData objectAtIndex:indexPath.row];
highscoreData = (SampleData *)[self.arrayOfSampleData objectAtIndex:indexPath.row]; //if above line doesn't work, use this
cell.textLabel.text=[NSString stringWithFormat:#"%# time %#",highscoreData.clueName, highscoreData.timeLog];
return cell;
}
#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
SampleData.h
#import <Foundation/Foundation.h>
#interface SampleData : NSObject
#property(nonatomic,strong) NSString * clueName;
#property(nonatomic,strong) NSString * timeLog;
#end
SampleData.m
#import "SampleData.h"
#implementation SampleData
#synthesize clueName,timeLog;
#end
SampleDataDAO.h
#import <Foundation/Foundation.h>
#import "SampleData.h"
#interface SampleDataDAO : NSObject
#property(nonatomic, strong) NSMutableArray * someDataArray;
-(NSMutableArray *)PopulateDataSource;
#end
SampleDataDAO.m (Not sure if this DAO NSObject is needed)
#import "SampleDataDAO.h"
#implementation SampleDataDAO
#synthesize someDataArray;
-(NSMutableArray *)PopulateDataSource
{
someDataArray = [[NSMutableArray alloc] init];
SampleData * mydata = [[SampleData alloc] init];
mydata = nil;
return someDataArray;
}
#end
There are several missteps in your coding:
You do need to use prepareForSegue to pass data from parent to child view controller. In your case from TimerViewController to HighScoreTableViewController.
In your HighScoreTableViewController class, create an iVar array that will hold the array of sampleData that you will pass over from TimerViewController instant via the prepareForSeque. Something like this:
HighScoreTableViewController.h
#property (nonatomic, strong) NSArray *arrayOfSampleData;
3 . In your prepareForSeque of the TimerViewController, this line is wrong:
//TimerViewController.highscoreData = [self.ds objectAtIndex:[self.tableView indexPathForSelectedRow].row];
Try this:
detailViewController.arrayOfSampleData = self.ds;
4 . In the HighScoreTableViewController.m, under viewDidLoad, replace this
highscoreData = (SampleData *)self.highscoreData;
with:
highscoreData = [SampleData alloc]init];
5 . In numberOfRowsInSection, you now can do this:
return self.arrayOfSampleData.count;
6 . In the cellForRowAtIndexPath,
highscoreData = [self.arrayOfSampleData objectAtIndex:indexPath.row];
//highscoreData = (SampleData *)[self.arrayOfSampleData objectAtIndex:indexPath.row]; //if above line doesn't work, use this
cell.textLabel.text = #"%# time %# ", highscoreData.clueName, highscoreData.timeLog;
In your HighScoreTableViewController you need access to your array e.g. by declaring and defining a writable property:
#property(nonatomic, strong) NSMutableArray *myArr;
then you can define
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.myArr count];
}
and
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ... like in your code
// Tried changing variable here and there base on tutorial, but can't seem to get it right.**
SampleData * sample = (SampelData *) [self.myArr objectAtIndex:indexPath.row];
cell.textLabel.text = #"%# time %# ",sample.clueName, sample.timeLog;
NSLog(#"Cell Value %d %#",indexPath.row, cell.textLabel.text);
return cell;
}
So basically you just have to change two lines in the definitions of your methods. Most of the time you work with TableViews it is like this: assign the array you want to read data from to a custom property. Return the size of the array in tableView:numberOfRowsInSection: and take an object from the appropiate index to populate a cell in tableView:cellForRowAtIndexPath:.
If the contents of your array changes you have to do extra action to update your table view.
First declare the array in .h file(ex. NSMutableArray *arrStopwatchDetails).
Create the property of that array like #property(nonatomic,retain)NSMutableArray *arrStopwatchDetails.
Synthesize the array in .m file like #synthesize arrStopwatchDetails.
Allocate the array in viewDidLoad or before you want to used.
ex. self.arrStopwatchDetails = [[NSMutableArray alloc]init];
In numberOfRowsInSection method, return the count of array similar to return [self.arrStopwatchDetails count].
In cellForRowsAtIndexPath method, assign value of array element to the cell text as
SampleData * sample = [[[SampleDataDAO alloc]init ].self.arrStopwatchDetails objectAtIndex:indexPath.row];
cell.textLabel.text = #"%# time %# ",sample.clueName, sample.timeLog;
Thats it.

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;
}