完成加载和显示UITableView
已正确填充的 a 后,我的应用程序然后崩溃并给出以下输出:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 14 beyond bounds [0 .. 13]'
我已经检查了导致 tableview 可能影响它的所有可变数组的内容,它们都返回了预期的数字[mutableArray count];
。最奇怪的部分是没有可以填充的单个可变数组,[0 .. 13]
因为整个应用程序中没有任何地方具有 14 个索引的数组。
UITableView
按预期返回单独的单元格,并且只调用一次cellForRowAtIndexPath
(使用检查NSLog
)。然后在视图出现后大约半秒到一秒崩溃NSRangeException
。
该类中唯一的可变数组UITableView
已被检查[mutableArray count];
并仅返回 1,这是生成的唯一单元格。
当控制台读数没有指示数组是什么或在哪里时,我该如何进行调试,并且突出显示的行只是 main 方法中自动释放的 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