无法从NSMutableArray(IPHONE SDK)获取自定义对象

时间:2011-04-12 19:46:35

标签: iphone nsmutablearray

我有一个NSMutableArray的问题...在我的函数中填充NSMutableArray(readRoutes)之后我无法提取对象....在readRoutes函数里面我可以...我无法想象在哪里是问题..

首先,NSMutableArray在readRoutes方法中填充Route对象...(在RoutesListView内部文件中)(我需要用这些Route对象填充TableView单元格...)

这是Route.h文件:

@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

Route.m文件:

#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

现在这是RoutesListView.h文件(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

在RoutesListView.m文件中:

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

当我填充NSMutableArray时,在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];
                [aId release];
                [aDirection release];
                [aName release];
                [aCode release];
            }

最后,当我设置CELL TEXTLABEL时......它崩溃了! :

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

帮助我明白......我失去了头发......

谢谢

马克西姆

1 个答案:

答案 0 :(得分:5)

您过度发布了几个通常会导致应用程序崩溃的对象。您的init函数也未在Route.m文件中正确实现。进行以下更改。

#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

接下来,您将释放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
}

最后,您将完全释放以下代码中的路径

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