【问题标题】:issue with array in didSelectRowAtIndexPath. Out of boundsdidSelectRowAtIndexPath 中的数组存在问题。越界
【发布时间】:2012-01-08 14:04:31
【问题描述】:

我正在尝试推送到将显示有关项目的全部信息的最终视图。

- (void)tableView:(UITableView *)atableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Item *itemObj; //object that holds data for cell for current view
ItemShow *itemOverViewObj; //data object for the next view 

if(atableView==self.tableView)
{
    //ordinary tabeView
    itemObj=[self.itemsArray objectAtIndex:[indexPath row]];
}
else
{
    //filtered with search tableView
    itemObj=[self.filteredItems objectAtIndex:[indexPath row]];
}

//The array which will store the data for overview 
NSMutableArray *itemsOverViewArr=[[NSMutableArray alloc]initWithCapacity:1];
DBAccess *access=[[DBAccess alloc]init];

//method for fetching data from db and inserting into array
itemsOverViewArr=[access getItemsOverView:itemObj.itemID];
[access closeDataBase];
[access release];

//here is the evil.
itemOverViewObj=[itemsOverViewArr objectAtIndex:[indexPath row]];
[itemsOverViewArr release];
    ItemOverView *iov=[[ItemOverView alloc]initWithNibName:@"ItemOverView" bundle:nil];
    iov.title=self.nominal;
    [iov setItemShow:itemOverViewObj];
    [self.navigationController pushViewController:iov animated:YES];
    [iov release];
}

我之前检查过的内容:

在 getItemsOverView 方法中选择 100% 有效。 itemObj.itemID 获取正确的 int。

问题源于 itemOverViewObj=[itemsOverViewArr objectAtIndex:[indexPath row]];

错误:* Terminating app due to unaught exception 'NSRangeException', reason: '* -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

DBAccess 类中的getItemsOverview 方法

-(NSMutableArray*)getItemsOverView:(int)itemID
{
NSMutableArray *itemsArray=[[[NSMutableArray alloc]init]autorelease];
const char *sqlItems=sqlite3_mprintf("SELECT itm.itemID,itm.itemYear,itm.rarity,dateComment,itm.mintage,dc.dateCode as dateCode,iaval.availability as avalibility,iaval.quality as quality,itm.Mintmark,itm.specialRemark\
                                     from items itm\
                                     join itemAvailability iaval on iaval.itemID=itm.itemID\
                                     join dateCultures dc ON dc.dateCultureID=itm.dateCulture\
                                     WHERE itm.itemID=%i",itemID);
sqlite3_stmt *statement;
int sqlResult = sqlite3_prepare_v2(database, sqlItems, -1, &statement, NULL);
if ( sqlResult== SQLITE_OK)
{
    while (sqlite3_step(statement) == SQLITE_ROW)
    {
        ItemShow *itemShow=[[ItemShow alloc]init];
        itemShow.itemID=sqlite3_column_int(statement, 0);
        char *itemYear=(char *)sqlite3_column_text(statement, 1);
        char *mintMark=(char *)sqlite3_column_text(statement, 2);
        char *masterMark=(char *)sqlite3_column_text(statement, 3);
        itemShow.rarity=sqlite3_column_int(statement, 4);
        itemShow.availability=sqlite3_column_int(statement, 5);
        itemShow.quality=sqlite3_column_int(statement, 6);
        char *mintage=(char *)sqlite3_column_text(statement, 7);

        itemShow.itemYear=(itemYear)?[NSString stringWithUTF8String:itemYear]:@"";
        itemShow.mintMark=(mintMark)?[NSString stringWithUTF8String:mintMark]:@"";
        itemShow.masterMark=(masterMark)?[NSString stringWithUTF8String:masterMark]:@"";
        itemShow.mintage=(mintage)?[NSString stringWithUTF8String:mintage]:@"Unknown";



        [itemsArray addObject:itemShow];
        [itemShow release];

    }
    sqlite3_finalize(statement);
}
else
{
    [self dbConnectionError];
}

return itemsArray;
}

提前谢谢你

【问题讨论】:

    标签: objective-c ios cocoa-touch


    【解决方案1】:

    异常消息说明了一切:您正在尝试访问 itemsOverViewArr 中的第二项(索引 1),但该数组仅包含一项(索引 0)。

    为什么会这样,因为您没有向我们展示相关代码,所以只有您自己才能知道。但它确实看起来像 [access getItemsOverView:itemObj.itemID] 返回一个包含 1 个元素的数组。

    此外,您的代码中至少存在一次内存泄漏。 NSMutableArray *itemsOverViewArr=[[NSMutableArray alloc]initWithCapacity:1]; 创建的数组在itemsOverViewArr=[access getItemsOverView:itemObj.itemID]; 行之后不再可达,因此无法释放。您稍后释放itemsOverViewArr 的事实可能也是内存管理错误(在这种情况下为过度释放),因为getItemsOverView: 应该返回一个自动释放的对象。 (顺便说一句,您不应将此类方法命名为 get...,因为此命名约定在 Cocoa 中暗示该方法通过指向方法参数之一的指针返回其结果。)

    【讨论】:

    • itemsOverViewArr=[access getItemsOverView:itemObj.itemID]; 后不为空,我写了 NSLog(@"%d",[itemsOverViewArr count]);检查它是否真的被填满。我得到 1。所以它被填满了。
    • @Nathan 1 表示一个元素,需要使用 objectAtIndex:0 来解决,因为索引数组是从零开始的。但是,您的原始报价表明该数组确实为空-因此您的报价不正确或最新的 NSLog 结果。
    • 那么这个实现呢?:NSMutableArray * itemsOverViewArr = [[NSMutableArray alloc] initWithArray: [access getItemsOverView:itemObj.itemID]];
    • 好的。同时这个问题已经结束,因为问题的原因被确定了。另一个问题将被打开。
    【解决方案2】:

    做什么:

    itemsOverViewArr=[access getItemsOverView:itemObj.itemID];
    

    做吗?

    如果它返回一个数组,像这样声明你的 NSMutableArray:

    NSMutableArray * itemsOverViewArr = [[NSMutableArray alloc] initWithArray: [access getItemsOverView:itemObj.itemID]];
    

    然后还要确保在引用它时,确保该可变数组中至少有一项。

    换句话说:

    if(itemsOverViewArr && ([itemsOverViewArr count] > 1)) 
    {
        itemOverViewObj=[itemsOverViewArr objectAtIndex:[indexPath row]];
        ...
        ...
    

    【讨论】:

    • 之前已经在我的代码中声明过:NSMutableArray *itemsOverViewArr=[[NSMutableArray alloc]initWithCapacity:1];
    • true... 你可以用我刚刚在答案中给你的内容替换你上面的声明,或者你也可以做[itemsOverViewArr setArray:[access getItemsOverView:itemObj.itemID]];(为你链接的文档)。
    • 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'+[Items count]: unrecognized selector sent to class 0x15f6c'
    • 并且 itemsOverViewArr 不为空。它充满了数据。
    • gah... 是我的错字,我已经修复了上面的代码(从 itemOverViewObjitemsOverViewArr)。
    【解决方案3】:

    看起来您将委托用于多个 tableView

    if(atableView==self.tableView)
    

    确保您在此处访问正确的表格视图:

    itemOverViewObj=[itemsOverViewArr objectAtIndex:[indexPath row]];
    

    否则您将在数组中获得错误的索引,该数组可能在索引 0 处只有一项,这会使索引 1 超出范围。

    【讨论】:

    • if(atableView==self.tableView) { //普通的tabeView itemObj=[self.itemsArray objectAtIndex:[indexPath row]]; } else { //用搜索表过滤 itemObj=[self.filteredItems objectAtIndex:[indexPath row]]; }
    • 第一个是普通表。使用 UISearch 排序后的另一个此表。两者都可以使用。
    • 在崩溃前执行 NSLog 以查看 itemsOverViewArr 中的内容以查看其中的内容。而 indexPath 是什么,这就是被调用的。我使用 [indexPath 描述]。
    • 我对 sqlite 真的一无所知,但作为一个建议,您可以在 itemsArray 返回之前检查它内部的内容。我会添加一些 NSLogs 来查看它在哪里以及是否有任何对象以及在哪里没有。很抱歉,我无法为您提供更多帮助。
    • -(NSMutableArray*)getItemsOverView:(int)itemID 在线。此方法从 db 中获取数据。
    猜你喜欢
    • 2012-11-04
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2018-06-21
    • 2012-10-28
    • 1970-01-01
    相关资源
    最近更新 更多