2011-05-02 6 views
0

si je tente de REUN le code ci-dessous je reçois un message de EXE_bad_access sur [nombre CatégorieListe]signal reçu "EXC_BAD_ACCESS" NSMutableArray

NSMutableArray *categoryList = [[CategoryItem alloc] getAll]; 
NSLog(@"number of items is %@", [categoryList count]); 

La classe est inférieure à

#import "CategoryItem.h" 

#import "SQLite.h" 

@interface CategoryItem : NSObject { 
    NSInteger ID; 
    NSInteger SortOrder; 
    NSString *Name; 
    NSString *ShoppingImage; 

} 

@property (nonatomic, nonatomic) NSInteger SortOrder; 
@property (nonatomic, retain) NSString * Name; 
@property (nonatomic, retain) NSString * ShoppingImage; 
@property (nonatomic, nonatomic) NSInteger ID; 

- (id)initWithObject:(NSInteger)itemID; 
-(NSMutableArray *)getAll; 

@end 
@implementation CategoryItem 


@synthesize ShoppingImage; 
@synthesize Name; 
@synthesize ID; 
@synthesize SortOrder; 

- (id)initWithObject:(NSInteger)itemID { 

    if ((self = [super init])) { 
     sqlite3 *database; 
     // Open the database. The database was prepared outside the application. 
     if (sqlite3_open([[SQLite fullFilePath] UTF8String], &database) == SQLITE_OK) { 
      // Get the primary key for all books. 
      const char *sql = "SELECT ID, Name, ShoppingImage, SortOrder FROM CategoryItem WHERE ID =?"; 
      sqlite3_stmt *statement; 
      // Preparing a statement compiles the SQL query into a byte-code program in the SQLite library. 
      // The third parameter is either the length of the SQL string or -1 to read up to the first null terminator.   
      if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) { 
       // We "step" through the results - once for each row. 
       sqlite3_bind_int(statement, 1, itemID); 

       while (sqlite3_step(statement) == SQLITE_ROW) { 
        // The second parameter indicates the column index into the result set. 
        self.ID = itemID; 
        self.Name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]; 
        self.ShoppingImage = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)]; 
        self.SortOrder = sqlite3_column_int(statement, 3); 
       } 
      } 
      // "Finalize" the statement - releases the resources associated with the statement. 
      sqlite3_finalize(statement); 
     } else { 
      // Even though the open failed, call close to properly clean up resources. 
      sqlite3_close(database); 
      NSLog(@"Failed to open database with message '%s'.", sqlite3_errmsg(database)); 
      // Additional error handling, as appropriate... 
     } 

    } 
    return self; 
} 

-(NSMutableArray*)getAll{ 

    NSMutableArray *listArray = [[[NSMutableArray alloc] init] autorelease]; 

    sqlite3 *database; 
    // Open the database. The database was prepared outside the application. 
    if (sqlite3_open([[SQLite fullFilePath] UTF8String], &database) == SQLITE_OK) { 
     // Get the primary key for all books. 
     const char *sql = "SELECT ID, Name, ShoppingImage, SortOrder FROM CategoryItem ORDER BY SortOrder"; 
     sqlite3_stmt *statement; 
     // Preparing a statement compiles the SQL query into a byte-code program in the SQLite library. 
     // The third parameter is either the length of the SQL string or -1 to read up to the first null terminator. 

     if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) 
     { 

      // We "step" through the results - once for each row. 
      while (sqlite3_step(statement) == SQLITE_ROW) 
      { 
       // The second parameter indicates the column index into the result set. 

       CategoryItem *categoryItem = [[CategoryItem alloc] init]; 

       categoryItem.ID = sqlite3_column_int(statement, 0); 
       categoryItem.Name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]; 
       categoryItem.ShoppingImage = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)]; 
       categoryItem.SortOrder = sqlite3_column_int(statement, 3); 

       [listArray addObject:categoryItem]; 

       [categoryItem release]; 
       categoryItem = nil; 

      } 


     }else{ 
      printf("could not prepare statemnt: %s\n", sqlite3_errmsg(database)); 
     } 
     // "Finalize" the statement - releases the resources associated with the statement. 
     sqlite3_finalize(statement); 

    } else { 
     // Even though the open failed, call close to properly clean up resources. 
     sqlite3_close(database); 
     NSLog(@"Failed to open database with message '%s'.", sqlite3_errmsg(database)); 
     // Additional error handling, as appropriate... 
    } 

    //NSLog(@"this is the list array count %@", [listArray count]); 

    return listArray; 
} 



- (void)dealloc { 
    [super dealloc]; 
    [Name release]; 
    [ShoppingImage release]; 

} 


@end 
+3

Seuls les masochistes utilisent directement l'API SQLite C dans Objective-C. [Utiliser FMDB] (http://github.com/ccgus/fmdb) (un encapsuleur SQLite) ou [CoreData] (http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreData/ cdProgrammingGuide.html) (un gestionnaire de graphe d'objets) à la place. –

+0

@Luke ne devriez-vous pas initialiser ce 'CategoryItem'? Vous appelez 'alloc' mais pas' initWithObject' ... – albertamg

+0

Vous n'avez pas initialisé la classe CategoryList, mais vous appelez une méthode dessus. Semble le problème est dans l'initialisation (inexistant). –

Répondre

2

Il ne semble juste la façon dont vous créez votre CategoryItem. Vous appelez alloc mais pas n'importe quelle méthode init.... Vous souhaiterez peut-être utiliser la méthode initWithObject que vous avez fournie dans votre implémentation.

De Apple docs:

Il faut deux étapes pour créer un objet utilisant Objective-C. Vous devez:

  • allouer la mémoire pour le Dynamiquement nouvel objet

  • Initialiser la nouvelle mémoire allouée aux valeurs appropriées

Un objet n'est pas entièrement fonctionnel jusqu'à ce que les deux étapes A été complété. Chaque étape est réalisée par un procédé séparé mais typiquement dans une seule ligne de code:

id = anObject [[alloc Rectangle] init];

EDIT:

Au-delà du problème d'initialisation, il semble y avoir un problème conceptuel (souligné par @Terry Wilcox): appel de la méthode getAll sur une instance ne semble pas logique et devrait donc être définie comme une méthode de classe au lieu:

+ (NSMutableArray*)getAll; 

et devrait être appelé comme ceci:

NSMutableArray *categoryList = [CategoryItem getAll]; 

EDIT 2:

Votre déclaration de journal ne semble pas juste non plus. [categoryList count] renvoie NSUInteger et vous essayez d'imprimer un objet avec %@. Utilisez %i à la place:

NSLog(@"number of items is %i", [categoryList count]); 
+2

Le code ne cherche pas à créer un CategoryItem, il essaie de créer un NSMutableArray. –

+0

Oui comme ci-dessus, j'appelle déjà alloc init? – Luke

+0

@Luke Vous essayez également de consigner un int comme s'il s'agissait d'un objet (voir EDIT 2) – albertamg

0

Ce code:

NSMutableArray *categoryList = [[CategoryItem alloc] getAll]; 

n'a pas de sens.Si getAll est une méthode de classe sur CategoryItem, alors il doit être défini comme

+ (NSMutableArray*)getAll; 

et vous devriez l'appeler comme

NSMutableArray *categoryList = [CategoryItem getAll]; 

Ensuite CatégorieListe sera un tableau que vous ne possédez pas, vous peut vouloir le conserver quand vous l'obtenez.

+0

merci pour ce code beaucoup plus propre! Ne résout pas encore mes problèmes de mémoire si – Luke

+0

Ce n'est pas le code plus propre, c'est le code de travail. Votre code d'origine ne fonctionnerait pas correctement, il n'appelle pas init donc votre méthode getAll peut ne rien retourner. –

Questions connexes