我的应用程序崩溃在不同的地方,但错误是相同的,只有索引有时更改,任何想法为什么发生这种情况我也附加了我的截图:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array' *** First throw call stack: (0x20d4012 0x1e34e7e 0x20760b4 0x152ba 0xdc4067 0xdc42db 0x14fca 0x16aa7 0x239253f 0x23a4014 0x2393fd6 0x23a4014 0x239b8b7 0x2397405 0x2394768 0x207aaf5 0x2079f44 0x2079e1b 0x2ca87e3 0x2ca8668 0xd78ffc 0x2b8d 0x2ab5) libc++abi.dylib: terminate called throwing an exception (lldb)
我已经尝试调试它以确定导致崩溃的确切位置或代码行但没有成功.它只是随机崩溃
谢谢
编辑1:
好吧,这是代码:
一旦获取,我将它们保存为:
-(void)saveTweetsArray:(NSMutableArray *)array{ NSString *dbPath = [DatabaseHelper databasePath]; sqlite3_stmt *statement; if(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK) { NSString *insertSql = [NSString stringWithFormat:@"delete from %@ where ACCOUNTID='%@'",[DatabaseHelper TweetsTable],self.accountId]; const char *insertStmt = [insertSql UTF8String]; sqlite3_prepare_v2(db, insertStmt, -1, &statement, NULL); if(sqlite3_step(statement) == SQLITE_DONE){ NSLog(@"old tweets removed"); } else{ NSLog(@" deletion failed"); NSLog(@"%@", [NSString stringWithUTF8String:(char*)sqlite3_errmsg(db)]); } sqlite3_finalize(statement); for(int i=0;i<[array count];i++){ NSMutableDictionary *dictionary = [array objectAtIndex:i]; NSString *insertSql = [NSString stringWithFormat:@"insert into %@ (ID,TWEET_TEXT,USER_NAME,ACCOUNTID) values (?,?,?,?)",[DatabaseHelper TweetsTable]]; const char *insertStmt = [insertSql UTF8String]; sqlite3_prepare_v2(db, insertStmt, -1, &statement, NULL); sqlite3_bind_text(statement, 1, [[dictionary valueForKey:@"id"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 2, [[dictionary valueForKey:@"text"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 3, [[dictionary valueForKey:@"userName"] UTF8String], -1, NULL); sqlite3_bind_text(statement, 4, [self.accountId UTF8String], -1, NULL); if(sqlite3_step(statement) == SQLITE_DONE) NSLog(@"data saved"); else{ NSLog(@"save failed"); NSLog(@"%@", [NSString stringWithUTF8String:(char*)sqlite3_errmsg(db)]); } sqlite3_finalize(statement); } sqlite3_close(db); }
这是我在获取新推文时在tableview上填充的地方:
-(NSMutableArray*)tweetsArray{ NSMutableArray* tweetsArray=[[NSMutableArray alloc] init]; NSString *dbPath = [DatabaseHelper databasePath]; if(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK) { const NSString *sql_stmt; sql_stmt= [NSString stringWithFormat:@"select ID,TWEET_TEXT,USER_NAME from %@ where ACCOUNTID='%@' ",[DatabaseHelper TweetsTable],self.accountId]; const char *sql_stmt1=[sql_stmt UTF8String]; sqlite3_stmt *compiledStatement; if(sqlite3_prepare_v2(db, sql_stmt1, -1, &compiledStatement, NULL) == SQLITE_OK) { // Loop through the results and add them to the feeds array while(sqlite3_step(compiledStatement) == SQLITE_ROW) { // Read the data from the result row NSMutableDictionary *dictionary=[[NSMutableDictionary alloc] init]; [dictionary setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)] forKey:@"id"]; [dictionary setValue:((char *)sqlite3_column_text(compiledStatement, 1))!=NULL?[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]:@"" forKey:@"text"]; [dictionary setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)] forKey:@"userName"]; [textsArray addObject:dictionary]; } sqlite3_finalize(compiledStatement); } } sqlite3_close(db); return textsArray; }
这是我在格式化后放在tableview上的地方:
-(void)formatTweetsAndPaintView{ NSArray *tweets = [dictionary valueForKey:@"twitter"]; //first save the old tweets to show while new are fetched NSMutableArray *tempTweets=[[NSMutableArray alloc] initWithArray:[baseController tweetsArray]]; //then clear the old tweets then format and fill array [[baseController tweetsArray] removeAllObjects]; if(tweets && tweets.count){ for(int i=0;i<[tweets count];i++){ NSMutableDictionary *tweetsDictionary = [[NSMutableDictionary alloc] init]; [tweetsDictionary setValue:[[tweets objectAtIndex:i] valueForKey:@"id_str"] forKey:@"id"]; [tweetsDictionary setValue:[[tweets objectAtIndex:i] valueForKey:@"text"] forKey:@"text"]; [tweetsDictionary setValue:[[[tweets objectAtIndex:i] valueForKey:@"user"] valueForKey:@"name"] forKey:@"userName"]; [[baseController tweetsArray] addObject:tweetsDictionary]; } } //include non duplicate tempTweet to tweetArray for(int i=0;i<[tempTweets count];i++){ if(![[baseController tweetsArray] containsObject:[tempTweets objectAtIndex:i]]) [[baseController tweetsArray] addObject:[tempTweets objectAtIndex:i]]; } if([dictionary valueForKey:@"twitter"]) [baseController setDictionary:[dictionary valueForKey:@"twitter"]]; [baseController reloadTableViewData]; //finally save the tweets [[TweetDB _instance] saveTweetsArray:[baseController tweetsArray]]; }
user1447414.. 8
如果要在程序崩溃时停止程序,则需要添加异常断点.
转到Breakpoint Navigator,单击加号按钮,然后选择Add Exception Breakpoint ...
在XCode 5中,它会立即添加它,但在以前的版本中,您需要选择:所有异常
这将停止在您的NSArray超出界限的位置,然后您可以调试.
编辑:
程序停止后,您应该能够在XCode中看到它崩溃的行.如果在XCode中没有看到该行,则可以在调试器类型中:
(lldb)bt
'bt'将打印程序完成的所有步骤,它将为您提供有关调用哪些方法的信息.
如果这不能提供您需要的信息,您可以尝试这种方式:
你的第二个选择是重复之前的步骤,而不是选择Add Exception Breakpoint ...你应该选择Ad Symbolic Breakpoint ...
选择后,弹出窗口将提示输入一些值.输入以下内容:
在崩溃之前它应该停止.此时,您可以导航到Debug Navigator以查看步骤,并找出位置:
如您所见,setPrivateProperty是在停止之前调用方法的最后一次.
如果Debug Navigator没有提供任何信息,您可以随时转到调试器并键入:
(lldb)bt
和以前一样,'bt'将追溯到更详细的所有步骤.
所有这些信息应足以调试您的程序.如果您需要帮助来解释'bt'输出,那就是另一个线程!
如果要在程序崩溃时停止程序,则需要添加异常断点.
转到Breakpoint Navigator,单击加号按钮,然后选择Add Exception Breakpoint ...
在XCode 5中,它会立即添加它,但在以前的版本中,您需要选择:所有异常
这将停止在您的NSArray超出界限的位置,然后您可以调试.
程序停止后,您应该能够在XCode中看到它崩溃的行.如果在XCode中没有看到该行,则可以在调试器类型中:
(lldb)bt
'bt'将打印程序完成的所有步骤,它将为您提供有关调用哪些方法的信息.
如果这不能提供您需要的信息,您可以尝试这种方式:
你的第二个选择是重复之前的步骤,而不是选择Add Exception Breakpoint ...你应该选择Ad Symbolic Breakpoint ...
选择后,弹出窗口将提示输入一些值.输入以下内容:
在崩溃之前它应该停止.此时,您可以导航到Debug Navigator以查看步骤,并找出位置:
如您所见,setPrivateProperty是在停止之前调用方法的最后一次.
如果Debug Navigator没有提供任何信息,您可以随时转到调试器并键入:
(lldb)bt
和以前一样,'bt'将追溯到更详细的所有步骤.
所有这些信息应足以调试您的程序.如果您需要帮助来解释'bt'输出,那就是另一个线程!