Программа получила сигнал "EXC_Bad_Access" NSMutableArray - PullRequest
0 голосов
/ 02 мая 2011

, если я попытаюсь повторно выполнить приведенный ниже код, я получаю сообщение EXE_bad_access на [categoryList count]

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

Класс ниже

#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

Ответы [ 2 ]

2 голосов
/ 02 мая 2011

Не похоже на то, как вы создаете CategoryItem.Вы вызываете alloc, но не init... метод.Возможно, вы захотите использовать метод initWithObject, который вы указали в своей реализации.

От Документы Apple :

Для созданияобъект с помощью Objective-C.Вы должны:

  • Динамически выделить память для нового объекта

  • Инициализировать вновь выделенную память для соответствующих значений

Объект не полностью функционален, пока оба шага не будут выполнены.Каждый шаг выполняется отдельным методом, но обычно в одной строке кода:

id anObject = [[Rectangle alloc] init];

РЕДАКТИРОВАТЬ:

Помимо проблемы инициализации, кажется, есть концептуальная проблема (на что указывает @Terry Wilcox): вызов метода getAll для экземпляра, кажется, не имеет смысла и поэтому должен быть определен какВместо этого используется метод класса:

+ (NSMutableArray*)getAll;

и должен вызываться следующим образом:

NSMutableArray *categoryList = [CategoryItem getAll];

РЕДАКТИРОВАТЬ 2:

Ваша запись в журнале не выглядиттоже верно.[categoryList count] возвращает NSUInteger, и вы пытаетесь напечатать объект с помощью %@.Используйте %i вместо:

NSLog(@"number of items is %i", [categoryList count]);
0 голосов
/ 03 мая 2011

Этот код:

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

не имеет смысла. Если getAll является методом класса для CategoryItem, то он должен быть определен как

+ (NSMutableArray*)getAll;

и вы должны назвать его как

NSMutableArray *categoryList = [CategoryItem getAll];

Тогда categoryList будет массивом, который вам не принадлежит, поэтому вы можете захотеть сохранить его, когда получите.

...