正しく入力された の読み込みと表示が完了するとUITableView
、アプリケーションがクラッシュし、次の出力が表示されます。
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 14 beyond bounds [0 .. 13]'
テーブルビューに影響を与える可能性のあるすべての可変配列の内容を確認しましたが、それらはすべて[mutableArray count];
. [0 .. 13]
最も奇妙な部分は、14 個のインデックスの配列を持つアプリ全体のどこにもないため、値を設定できる単一の可変配列がないことです。
はUITableView
期待どおりに孤独なセルを返し、1 回だけ呼び出しますcellForRowAtIndexPath
( を使用して確認NSLog
)。ビューが表示されてから約0.5秒から1秒後にクラッシュしますNSRangeException
。
クラス内の唯一の変更可能な配列UITableView
がチェックされ[mutableArray count];
、生成された唯一のセルである 1 だけが返されます。
コンソールの読み出しが配列の内容や場所を示しておらず、強調表示されている行がメイン メソッドの自動解放の SIGBART にすぎない場合、これをデバッグするにはどうすればよいですか?
クラッシュが発生したビューのコード:
ヘッダファイル:
#import <UIKit/UIKit.h>
#import "ActionNote.h"
#import <sqlite3.h>
#import "DBAccess.h"
#import "ActionNoteViewDetails.h"
@class ActionNoteViewDetails;
@interface ActionNoteListingViewByDates : UITableViewController<UITableViewDataSource, UITableViewDelegate>{
NSInteger domain_id;
NSString *url;
NSString *selectedDate;
NSString *dbname;
NSString *dbpath;
sqlite3 *database;
sqlite3_stmt *selStmt;
sqlite3_stmt *delStmt;
sqlite3_stmt *insStmt;
NSMutableArray *items;
BOOL copyDb;
NSString *graphtype;
ActionNoteViewDetails *actionNoteViewDetails;
}
@property (nonatomic, strong) ActionNoteViewDetails *actionNoteViewDetails;
@property (nonatomic, retain) NSString *url;
@property (nonatomic, readwrite) NSInteger domain_id;
@property (nonatomic, retain) NSString *graphtype;
@property (nonatomic, retain) NSString *selectedDate;
@property (nonatomic, retain) NSMutableArray *items;
-(void) openDatabase;
-(void) readItems;
-(void) closeDatabase;
-(void) detailView:(NSIndexPath *)path;
@end
m ファイル:
#import "ActionNoteListingViewByDates.h"
@implementation ActionNoteListingViewByDates
@synthesize domain_id;
@synthesize url;
@synthesize items;
@synthesize graphtype;
@synthesize selectedDate;
@synthesize actionNoteViewDetails;
- (void)viewDidLoad {
[super viewDidLoad];
items = [[NSMutableArray alloc] init]; // array for items
copyDb = TRUE; // set copy / create flag
// set up for app
dbname = @"yodelaydb.sqlite3"; // database name
// get full path of database in documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
dbpath = [[path stringByAppendingPathComponent:dbname] retain];
database = nil;
selStmt = nil;
delStmt = nil;
insStmt = nil;
[self openDatabase]; // open database
[self readItems];
self.title = selectedDate;
self.tableView.allowsSelectionDuringEditing = true;
[self.navigationController setToolbarHidden:NO];
}
-(void) detailView:(NSIndexPath *)path {
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if(UIDeviceOrientationIsPortrait(deviceOrientation)){
self.actionNoteViewDetails= [[self.storyboard instantiateViewControllerWithIdentifier:@"IDActionNoteViewDetails"] retain];
if (path != nil) {
ActionNote *i = (ActionNote *) [items objectAtIndex:path.row];
NSLog(@"actionnote i %d",path.row);
actionNoteViewDetails.note_id = i.note_id;
actionNoteViewDetails.notetitle =i.title;
actionNoteViewDetails.notecontent =i.content;
actionNoteViewDetails.SelectedDate=i.notes_date;
actionNoteViewDetails.SelectedProfile=i.domainname;
actionNoteViewDetails.domain_id = i.domain_id;
actionNoteViewDetails.actionmedium = i.actionMedium;
actionNoteViewDetails.actionsource = i.actionSource;
actionNoteViewDetails.dataFromGraph = YES;
}
else{
actionNoteViewDetails.note_id = 0;
}
[self.navigationController pushViewController:actionNoteViewDetails animated:TRUE];
}
if (UIDeviceOrientationIsLandscape(deviceOrientation)){
self.actionNoteViewDetails= [[self.storyboard instantiateViewControllerWithIdentifier:@"IDActionNoteViewDetailsLandscape"] retain];
if (path != nil) {
ActionNote *i = (ActionNote *) [items objectAtIndex:path.row];
actionNoteViewDetails.note_id = i.note_id;
actionNoteViewDetails.notetitle =i.title;
actionNoteViewDetails.notecontent =i.content;
actionNoteViewDetails.SelectedDate=i.notes_date;
actionNoteViewDetails.SelectedProfile=i.domainname;
actionNoteViewDetails.domain_id = i.domain_id;
actionNoteViewDetails.actionmedium = i.actionMedium;
actionNoteViewDetails.actionsource = i.actionSource;
actionNoteViewDetails.dataFromGraph = YES;
}
else{
actionNoteViewDetails.note_id = 0;
}
[self.navigationController pushViewController:actionNoteViewDetails animated:TRUE];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationItem.hidesBackButton = NO;
[self.navigationController setToolbarHidden:YES];
self.navigationController.navigationBarHidden=NO;
[self.tableView reloadData];
}
-(void)dealloc{
[actionNoteViewDetails release];
[selectedDate release];
[url release];
[dbname release];
[dbpath release];
[items release];
[super dealloc];
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [items count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
}
ActionNote *i = (ActionNote *) [items objectAtIndex:indexPath.row];
NSString *displayedTitle = i.actionMedium;
NSString *displayedContent = i.content;
cell.textLabel.text = displayedTitle;
cell.textLabel.font = [UIFont systemFontOfSize:15];
cell.detailTextLabel.text = displayedContent;
cell.detailTextLabel.font = [UIFont systemFontOfSize:11];
if([displayedTitle isEqualToString:@"Twitter"]){
UIImage *theImage = [UIImage imageNamed:@"bird_48_blue.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Blogging"]){
UIImage *theImage = [UIImage imageNamed:@"rss_icon.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Affiliate Marketing"]){
UIImage *theImage = [UIImage imageNamed:@"affiliate-marketing.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Online Press Release"]){
UIImage *theImage = [UIImage imageNamed:@"press-release.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Public Speaking"]){
UIImage *theImage = [UIImage imageNamed:@"public-speaking.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Video"]){
UIImage *theImage = [UIImage imageNamed:@"video.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Email Campaign"]){
UIImage *theImage = [UIImage imageNamed:@"email.png"];
cell.imageView.image = theImage;
}else if([displayedTitle isEqualToString:@"Offline Press Release"]){
UIImage *theImage = [UIImage imageNamed:@"press-release.png"];
cell.imageView.image = theImage;
}else{
UIImage *theImage = [UIImage imageNamed:@"action-note.png"];
cell.imageView.image = theImage;
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// get the item for this cell
[self detailView:indexPath];
}
-(void)openDatabase {
BOOL ok;
NSError *error;
NSFileManager *fm = [NSFileManager defaultManager]; // file manager
ok = [fm fileExistsAtPath:dbpath];
// if database not there, copy from resource to path
if (!ok)
{
if (copyDb)
{ // copy the database
// location in resource bundle
NSString *appPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:dbname];
// copy from resource to where it should be
ok = [fm copyItemAtPath:appPath toPath:dbpath error:&error];
}
}
//[fm release];
// open database
if (sqlite3_open([dbpath UTF8String], &database) != SQLITE_OK)
{
sqlite3_close(database); // in case partially opened
database = nil; // signal open error
}
if (!copyDb && !ok)
{ // first time and database not copied
ok = TRUE;//[self createDatabase]; // create empty database
}
if (!ok)
{ // problems creating database
//NSAssert1(0, @"Problem creating database [%@]", [error localizedDescription]);
}
}
-(void)readItems {
if (!database) return; // earlier problems
// build select statement
if (!selStmt)
{
const char *sql = "SELECT note_id,title,settingid,domain_id,content,notes_date,domainname,actionSource,actionMedium,iscompleted FROM notes where iscompleted=1 and notes_date=? order by notes_date";
if (sqlite3_prepare_v2(database, sql, -1, &selStmt, NULL) != SQLITE_OK)
{
selStmt = nil;
}
sqlite3_bind_text(selStmt, 1, [selectedDate UTF8String] , -1, SQLITE_TRANSIENT);
}
if (!selStmt)
{
NSAssert1(0, @"Can't build SQL to read notes [%s]", sqlite3_errmsg(database));
}
int ret;
while ((ret=sqlite3_step(selStmt))==SQLITE_ROW)
{ // get the fields from the record set and assign to item
// primary key
NSInteger n = sqlite3_column_int(selStmt, 0);
ActionNote *item = [[ActionNote alloc] initWithPrimaryKey:n]; // create item
// item name
char *s = (char *)sqlite3_column_text(selStmt, 1);
if (s==NULL) s = "";
item.title = [NSString stringWithUTF8String:(char *)s];
NSInteger settingid = sqlite3_column_int(selStmt, 2);
item.settingid = settingid;
NSInteger domainid = sqlite3_column_int(selStmt, 3);
item.domain_id = domainid;
// item name
char *content = (char *)sqlite3_column_text(selStmt, 4);
if (content==NULL) content = "";
item.content = [NSString stringWithUTF8String:(char *)content];
// item name
char *notes_date = (char *)sqlite3_column_text(selStmt, 5);
if (notes_date==NULL) notes_date = "";
item.notes_date = [NSString stringWithUTF8String:(char *)notes_date];
// item name
char *domainname = (char *)sqlite3_column_text(selStmt, 6);
if (domainname==NULL) domainname = "";
item.domainname = [NSString stringWithUTF8String:(char *)domainname];
// NSLog(@"domain name %@",item.domainname);
// item name
char *actionSource = (char *)sqlite3_column_text(selStmt, 7);
if (actionSource==NULL) actionSource = "";
item.actionSource = [NSString stringWithUTF8String:(char *)actionSource];
// NSLog(@"actionSource %@",item.actionSource);
// item name
char *actionMedium = (char *)sqlite3_column_text(selStmt, 8);
if (actionMedium==NULL) actionMedium = "";
item.actionMedium = [NSString stringWithUTF8String:(char *)actionMedium];
// NSLog(@"actionMedium %@",item.actionMedium);
// item name
NSInteger completed = sqlite3_column_int(selStmt, 9);
item.iscompleted = completed;
[items addObject:item]; // add to list
[item release]; // free item
}
sqlite3_reset(selStmt); // reset (unbind) statement
[self closeDatabase];
}
-(void)closeDatabase {
sqlite3_finalize(selStmt); // release memory
sqlite3_close(database);
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
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)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
return YES;
}
@end