简体   繁体   中英

Can't get custom object from NSMutableArray (IPHONE SDK)

I have a problem with a NSMutableArray... After I fill the NSMutableArray in my function (readRoutes) I can't extract the objects.... Inside the readRoutes function I can... I can't figure where is the problem..

First the NSMutableArray is fill with Route objects in the readRoutes method...(Inside RoutesListView file) (I need to fill after TableView cells with these Route objects...)

This is the Route.h file :

@interface Route : NSObject {
    NSString *routeId;
    NSString *routeDirection;
    NSString *routeName;
    NSString *routeCode;
}
@property (nonatomic,retain) NSString *routeId;
@property (nonatomic,retain) NSString *routeDirection;
@property (nonatomic,retain) NSString *routeName;
@property (nonatomic,retain) NSString *routeCode;

-(id)initWithName:(NSString *)name direction:(NSString *)d routeId:(NSString *)rid code:(NSString *)c;
@end

The Route.m file:

#import "Route.h"

@implementation Route
@synthesize routeId;
@synthesize routeDirection;
@synthesize routeName;
@synthesize routeCode;

-(id)initWithName:(NSString *)name direction:(NSString *)d routeId:(NSString *)rid code:(NSString *)c{
    self.routeId=rid;
    self.routeName=name;
    self.routeDirection=d;
    self.routeCode=c;
    return self;
}
@end

Now this is the RoutesListView.h file (a UITableViewController)

#import <UIKit/UIKit.h>
#import "Route.h"

@interface RoutesListView : UITableViewController  <UITableViewDelegate,UITableViewDataSource> {
    NSMutableArray *routeArray;
    NSString *dbName;
    NSString *dbPath;
}
@property (nonatomic,retain) NSMutableArray *routeArray;
@property (nonatomic,retain) NSString *dbName;
@property (nonatomic,retain) NSString *dbPath;

-(void)readRoutes;
@end

Inside the RoutesListView.m file :

#import "RoutesListView.h"
#import "Route.h"
#import <sqlite3.h>

@implementation RoutesListView

@synthesize routeArray;
@synthesize dbName,dbPath;

#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad {
    dbName = @"data.db";
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    dbPath = [documentsDir stringByAppendingPathComponent:dbName];
    routeId =[[NSMutableArray alloc] init];

    //routeArray

        NSMutableArray * array = [[NSMutableArray alloc] init]; 
    self.routeArray = array;


    [array release];
    [self readRoutes];
    [super viewDidLoad];
}

INSIDE THE readRoutes method when I fill the NSMutableArray (The method work fine...):

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {

                // Read the data from the result row
                NSString *aId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                NSString *aDirection =[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
                NSString *aCode = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

                Route *maRoute = [[Route alloc] initWithName:aName direction:aDirection routeId:aId code:aCode];

                                // I fill the NSMutableArray here...
                [routeArray addObject:maRoute];

                                [maRoute release];
                [aId release];
                [aDirection release];
                [aName release];
                [aCode release];
            }

FINALLY WHEN I SET THE CELL TEXTLABEL...IT CRASH! :

- (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...
    NSUInteger row = [indexPath row];
    Route *myRoute = (Route *)[routeArray objectAtIndex:row];
    cell.textLabel.text = myRoute.routeName;
    [myRoute release];
    return cell;
}

Help me to understand... I lost my hair on that...

Thanks

Maxime

You are over releasing several objects which will usually cause your application to crash. Also your init function is not properly implemented inside of your Route.m file. Make the following changes.

#import "Route.h"

@implementation Route
@synthesize routeId;
@synthesize routeDirection;
@synthesize routeName;
@synthesize routeCode;

-(id)initWithName:(NSString *)name direction:(NSString *)d routeId:(NSString *)rid code:(NSString *)c{
    //Must call supers implementation of init
    self = [super init];
    if(self)
    {
        self.routeId=rid;
        self.routeName=name;
        self.routeDirection=d;
        self.routeCode=c;
    }
    return self;
}
@end

Next you are over releasing objects inside of readRoutes

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
    // Read the data from the result row
    NSString *aId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
    NSString *aDirection =[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
    NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
    NSString *aCode = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

    Route *maRoute = [[Route alloc] initWithName:aName direction:aDirection routeId:aId code:aCode];

    // I fill the NSMutableArray here...
    [routeArray addObject:maRoute];

    [maRoute release]; //This is right you called alloc/init
    [aId release];       //This is wrong never retained,copy or alloc/init
    [aDirection release];//Dont release here either
    [aName release];     //Dont release
    [aCode release];     //Dont release
}

And finally you are over releasing the route inside of the following code

- (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...
    NSUInteger row = [indexPath row];
    Route *myRoute = (Route *)[routeArray objectAtIndex:row];
    cell.textLabel.text = myRoute.routeName;

    [myRoute release]; //Do not release route here

    return cell;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM