尝试使用从sql + NSRangeException检索的数据填充表视图控制器时出现异常

时间:2012-11-10 17:05:18

标签: ios sqlite ios6

我是iOS开发的新手,我遇到了奇怪的问题(因为表视图控制器和sql类中的相同代码与其他实体的效果相当不错)。

我正在尝试将数据从sqlite数据库检索到我的表视图控制器 ..

当我尝试在数据库中插入多条记录时,此错误会显示 2012-11-10 19:04:20.577我的应用程序[7032:11303] *由于未捕获的异常'NSRangeException'终止应用程序,原因:'* - [__ NSArrayI objectAtIndex:]:索引1超出范围[0 .. 0]' * 第一次抛出调用堆栈:

任何帮助将不胜感激。 谢谢。


import <UIKit/UIKit.h>
import "Category.h"
import "DbOperations.h"
import "AddCategoriesTVC.h"
import "CategoryDetailTVC.h"@interface CategoriesTVC : UITableViewController <UITableViewDataSource, UITableViewDelegate,AddCategoriesTVCDelegate, CategoryDetailTVCDelegate>

@property (strong, nonatomic) Category *categoryItem;
@property(nonatomic, strong) DbOperations * ops;
@property(nonatomic, strong) NSMutableArray * myCategoryArray;
@property (strong, nonatomic) IBOutlet UITableView * categoryTable;
@end
///////////
import "CategoriesTVC.h"
import "Category.h"
import "DbOperations.h"
import "sqlite3.h"
@implementation CategoriesTVC
@synthesize categoryTable;
@synthesize categoryItem,myCategoryArray,ops;

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

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

#pragma mark - View lifecycle

- (void)viewDidLoad
{ops = [[DbOperations alloc]init];
[ops selectCategories];
myCategoryArray = [ops categoryArray];
self.editButtonItem.title = @"edit";
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[super viewDidLoad];
}


- (void)viewDidUnload
{
[self setCategoryTable:nil];
[super viewDidUnload];
}

- (void)viewWillAppear:(BOOL)animated
{[super viewWillAppear:animated];
//myCategoryArray =[[NSMutableArray alloc]init];//]
[ops selectCategories];
myCategoryArray = [ops categoryArray];
[categoryTable reloadData];}

//pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
// Return the number of sections.
return 1;}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
 NSLog(@"JJJJ2");
// Return the number of rows in the section.
return [self.myCategoryArray count];}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"Category Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

Category * categoryObj = [ops.categoryArray objectAtIndex:indexPath.row];
cell.textLabel.text = categoryObj.categoryName;
cell.textLabel.textAlignment = NSTextAlignmentCenter;//UITextAlignmentCenter;

return cell;}

@interface DbOperations : NSObject
{
sqlite3 * db;
}
//to add the contents of the database which will be the data source for the table
@property(nonatomic,strong)NSMutableArray * categoryArray;

//instance methods for ** Category Entity **

-(void) selectCategories;
-(void) insertCategory:(NSString *)categoryName;
-(void) updateCategory:(NSString *)categoryName:(NSString *)categoryName2;
-(void) deleteCategory:(NSString *)categoryName;
------------------------------------------
------------------------------------------
-(void) selectCategories{

categoryArray = [[NSMutableArray alloc] init];
//Get list of directories in Document path
NSArray * dirPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

//Define new path for database
NSString * documentPath = [[dirPath objectAtIndex:0] stringByAppendingPathComponent:@"SmartSpeakerDB.sqlite"];
//By default there should only have one item in the array, so the index is always 0 unless you add subdirectories.

if(!(sqlite3_open([documentPath UTF8String], &db) == SQLITE_OK))
{
    NSLog(@"An error has occured.");

    return;
}else{//e2


    const char *sql = "SELECT categoryName FROM Category";
    //const char * sql, will be execute the SELECT statement.
    sqlite3_stmt *sqlStatement;


    if(sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
    {
        NSLog(@"There is a problem with prepare statement Hah");
        return;
    }else{
        while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
             NSLog (@"ENTER while");

 char * checkChar = (char*)sqlite3_column_text(sqlStatement,0);//1
    if (checkChar!= NULL) {
        NSString *s=[NSString stringWithUTF8String:checkChar];
                Category * newCategory = [[Category alloc] init];
        newCategory.categoryName = s;

             NSLog (@"***");
                [categoryArray addObject:newCategory];
            NSLog(@"Name %@",newCategory.categoryName);
               newCategory = nil;

     }//END IF
        }//END While
        sqlite3_finalize(sqlStatement);
        sqlite3_close(db);
    }//END ELSE 1
}//END ELSE 2
}//End

2 个答案:

答案 0 :(得分:0)

我看起来可能是因为你正在使用:

[self.myCategoryArray count];

numberOfRowsInSection但是:

[ops.categoryArray objectAtIndex:indexPath.row];
cellForRowAtIndexPath中的

如果两个数组具有不同数量的对象,那么您将遇到此问题。您通常对两个函数使用相同的数组,以便不会发生这种情况。

答案 1 :(得分:0)

您没有说明所有代码中您实际遇到问题的位置,但我发现了一个可能的问题。在您返回的tableView:numberOfRowsInSection:方法中:

[self.myCategoryArray count];

但是在你的tableView:cellForRowAtIndexPath:方法中,你打电话:

Category * categoryObj = [ops.categoryArray objectAtIndex:indexPath.row];

您在这里使用两个不同的阵列。这些应该基于相同的数据。

为了将来参考,在发布这些类型的问题时,请指出异常来自的确切行,并仅发布相关代码。