【问题标题】:iOS UItableView remove object from array by index pathiOS UItableView 通过索引路径从数组中删除对象
【发布时间】:2015-04-09 18:05:45
【问题描述】:

我有按 A-Z 部分排序的自定义通讯录。我正在尝试将所选联系人添加到数组中

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSMutableDictionary *contactInfo = [NSMutableDictionary new];

Cell *cell = (Cell *)[self.contTableView cellForRowAtIndexPath:indexPath];

//NSLog(@"CELL %@", cell.contact.fullname);

if (!cell.contact.contactChecked) {

    cell.contactImage.image = [UIImage imageNamed:@"cell_blue_circle.png"];
    cell.contact.contactChecked = YES;
    //NSLog(@"DID SELECT %@", cell.contact.fullname);
    NSLog(@"index checked row %d section %d", indexPath.row, indexPath.section);
    [contactInfo setValue:cell.contact.fullname forKey:@"name"];
    [contactInfo setValue:cell.contact.numbers.firstObject forKey:@"phone"];

    [self.seletedPeople insertObject:contactInfo atIndex:indexPath.row];

} else {
     NSLog(@"index unchecked row %d section %d", indexPath.row, indexPath.section);
    cell.contactImage.image = [UIImage imageNamed:@"cell_gray_circle.png"];
    cell.contact.contactChecked = NO;
    [self.seletedPeople removeObjectAtIndex:indexPath.row];
}

NSLog(@"DICT SELECTED %@", self.seletedPeople);

}

发生了什么,在某些单元应用程序中因错误而崩溃

* 由于未捕获的异常 'NSRangeException' 导致应用程序终止,原因:'* -[__NSArrayM insertObject:atIndex:]: index 1 beyond 空数组的边界' *** 第一次抛出调用堆栈:(0x29c02fef 0x38150c8b 0x29b1cf8f 0xf7fe9 0x2d36e56b 0x2d41d43b 0x2d2d2a91 0x2d24d38f 0x29bc8fed 0x29bc66ab 0x29bc6ab3 0x29b13201 0x29b13013 0x313f2201 0x2d2b7a59 0x10c075 0x386dcaaf) libc++abi.dylib: 以未捕获的异常终止 输入 NSException

更新:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *cellID = @"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];

if (searchResults) {

    //NSLog(@"CELL %@", cell.contact.fullname);
    contact = [searchResults objectAtIndex:indexPath.row];
    cell.contact = contact;
    cell.firstNameLabel.text = contact.fullname;
    cell.avatar.image = contact.image;
    cell.avatar.layer.borderColor = [UIColor grayColor].CGColor;
    cell.avatar.layer.borderWidth = 0.5;
    cell.avatar.layer.cornerRadius = 25.0;
    cell.avatar.layer.masksToBounds = YES;
    cell.number.text = contact.numbers.firstObject;

} else {

    NSString *sectionTitle = [[[namesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]
                              objectAtIndex:indexPath.section];
    NSArray *sectionContacts = [namesDictionary objectForKey:sectionTitle];
    contact = [self getContactFromArray:[sectionContacts objectAtIndex:indexPath.row]];

    cell.firstNameLabel.text = [sectionContacts objectAtIndex:indexPath.row];

    cell.avatar.image = contact.image;
    cell.avatar.layer.borderColor = [UIColor grayColor].CGColor;
    cell.avatar.layer.borderWidth = 0.5;
    cell.avatar.layer.cornerRadius = 25.0;
    cell.avatar.layer.masksToBounds = YES;
    cell.number.text = contact.numbers.firstObject;

    cell.contact = contact;

    cell.tag = indexPath.row;
}

if (contact.contactChecked) {
    cell.contactImage.image = [UIImage imageNamed:@"cell_blue_circle.png"];
} else {
    cell.contactImage.image = [UIImage imageNamed:@"cell_gray_circle.png"];

}


return cell;

}

【问题讨论】:

  • 请发布代码以显示 cellForRowAtIndexPath:更好地了解您的单元格显示方式
  • 请看我更新的帖子

标签: ios objective-c arrays uitableview


【解决方案1】:

我在这种情况下使用的方式。我创建一个模型类并用模型加载表格视图。现在,当我选择一个单元格或取消选择一个单元格时。我只是将该模型添加到另一个数组中。之后,当我取消选择已选择的单元格时,我可以从 indexpath.row 中获取相同的模型,然后我可以使用 NSArray 方法在该选定数组中获取该模型并将其从那里删除。要解决您的问题,您可以在选择过程中使用 indexPath.row 作为字典中的另一个键。之后,当您取消选择单元格时,使用谓词从用于存储所选单元格的数组中获取添加的字典。找到后将其从数组中删除。

【讨论】:

  • 我已经用支票更新了您的答案。请务必更新您的代码,否则它会崩溃。
【解决方案2】:

这里的问题是模型与视图对象的耦合,您不应该从视图本身(在您的情况下为Cell)查询某个属性,但是检查的联系人应该从数据源对象(您用来提供 cellForRowAtIndexPath: 的对象,应该从中查询它。

否则,由于耦合可能导致代码错误且不稳定,因为它可能指向一个空对象

【讨论】:

    【解决方案3】:

    问题出在这里:

    [self.seletedPeople insertObject:contactInfo atIndex:indexPath.row];
    

    如果selectedPeople 为空并且用户单击第2 行,那么它将尝试将contactInfo 插入“超出空数组的范围”的第2 行。只需使用 addObject: 代替。您还需要更改从该数组中删除项目的方式(最好使用字典代替)。

    【讨论】:

    • 我删除对象的问题。这 2 个对象是字典,算作 1 个对象
    【解决方案4】:

    解决方案是将联系人记录 ID 添加到我的字典中,并使用谓词此联系人 ID 进行搜索。然后删除它。感谢@jassi

     - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    
    
        NSMutableDictionary *contactInfo = [NSMutableDictionary new];
    
        Cell *cell = (Cell *)[tableView cellForRowAtIndexPath:indexPath];
    
        if (!cell.contact.contactChecked) {
    
            cell.contactImage.image = [UIImage imageNamed:@"cell_blue_circle.png"];
            cell.contact.contactChecked = YES;
            //NSLog(@"DID SELECT %@", cell.contact.fullname);
            NSLog(@"index checked %@ ", [indexPath description]);
            [contactInfo setValue:cell.contact.fullname forKey:@"name"];
            [contactInfo setValue:cell.contact.numbers.firstObject forKey:@"phone"];
            [contactInfo setValue:@(cell.contact.contactId) forKey:@"contactId"];
    
    
            [self.seletedPeople addObject:contactInfo];
    
        } else {
             NSLog(@"index unchecked %@", [indexPath description]);
            cell.contactImage.image = [UIImage imageNamed:@"cell_gray_circle.png"];
            cell.contact.contactChecked = NO;
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"contactId == %d", cell.contact.contactId];
            NSArray *resultTemp = [self.seletedPeople filteredArrayUsingPredicate:predicate];
    
        if(resultTemp.count>0)
            [self.seletedPeople removeObject:resultTemp[0]];
    
    
        }
    
        NSLog(@"DICT SELECTED %@", self.seletedPeople);
    }
    

    【讨论】:

      【解决方案5】:

      正如 user2320861 所说,问题出在您使用 insertObject 的那一行。我会做以下事情:

      1. 使用以下代码将 self.selectedPeople 更改为 NSMutableDictionary:

        //in your @interface
        @property (nonatomic, strong) NSMutableDictionary *selectedPeople;
        
      2. 将didSelectCellAtIndexPath中的代码改为:

        //Since phone numbers are unique.
        self.selectedPeople[cell.contact.numbers.firstObject] = contactInfo;
        
      3. 稍后使用此代码检索所有联系人:

        for(id key in self.selectedPeople) {
            NSDictionary contactInfo = [self.selectedPeople objectForKey:key];
            //Do something with that contactInfo
        }
        

      【讨论】:

      • 不明白您的回答。我不需要找回它。我需要取消选择并从数组中删除我已点击两次的对象。在某些索引中它运行良好,而在某些索引中它正在崩溃
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2021-09-15
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多