-1

私はiOS開発に不慣れで、奇妙な問題に直面しています(テーブルビューコントローラーとSQLクラスの両方で同じコードが他のエンティティでうまく機能するため)。

sqliteデータベースからテーブルビューコントローラーにデータを取得しようとしています..

データベースに複数のレコードを挿入しようとすると、このエラーが表示されます。 2012-11-10 19:04:20.577 my app[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
4

2 に答える 2

0

おそらくあなたが使用しているためだと思われます:

[self.myCategoryArray count];

しかしnumberOfRowsInSection

[ops.categoryArray objectAtIndex:indexPath.row];

cellForRowAtIndexPath

2 つの配列のオブジェクト数が異なる場合、この問題が発生します。これが起こらないように、通常は両方の関数に同じ配列を使用します。

于 2012-11-10T17:13:59.753 に答える
0

そのコード全体のどこで実際に問題が発生しているかは述べていませんが、可能性のある問題が 1 つあります。tableView:numberOfRowsInSection:メソッドでは、次を返します。

[self.myCategoryArray count];

しかし、その後、tableView:cellForRowAtIndexPath:メソッドで次のように呼び出します。

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

ここでは 2 つの異なる配列を使用しています。これらは同じデータに基づいている必要があります。

今後の参考のために、これらのタイプの質問を投稿するときは、例外が発生している正確な行を指摘し、関連するコードのみを投稿してください。

于 2012-11-10T17:14:06.973 に答える