iOS UItableView удаляет объект из массива по пути указателя

89
11

У меня есть контактная книга, отсортированная по разделам AZ. Я пытаюсь добавить к выбранному массиву контакты

- (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:]: индекс 1 за пределами для пустого массива' *** Первый стек вызова броска: (0x29c02fef 0x38150c8b 0x29b1cf8f 0xf7fe9 0x29b1cf8f 0x2d41d43b 0x2d2d2a91 0x2d24d38f 0x29bc8fed 0x29bc66ab 0x29bc6ab3 0x29b13201 0x29b13013 0x313f2201 0x2d2b7a59 0x10c075 0x386dcaaf) libС++ 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;

}

спросил(а) 2021-01-25T15:59:03+03:00 4 месяца, 4 недели назад
1
Решение
78

То, как я использую в таких случаях. Я создаю класс модели и загружаю tableview с помощью моделей. Теперь, когда я выбираю ячейку или снимаю выделение ячейки. Я просто добавляю эту модель в другой массив. После этого, когда я выбираю уже выбранную ячейку, я могу получить одну и ту же модель из indexpath.row, а затем я могу использовать метод NSArray для извлечения этой модели в выбранном массиве и удалить ее оттуда. Чтобы исправить вашу проблему, вы можете использовать indexPath.row как другой ключ в словаре во время выбора. После этого, когда вы отмените выбор ячейки, используйте предикат, чтобы получить добавленный словарь из массива, который вы используете для хранения выбранных. Как только вы обнаружите, что он удаляет его из массива.

ответил(а) 2021-01-25T15:59:03+03:00 4 месяца, 4 недели назад
63

проблема здесь заключается в сочетании модели с объектами представления, вы не должны запрашивать об определенном свойстве из самого представления (в вашем случае Cell), однако проверенный контакт должен иметь отражение своей модели от объекта источника данных ( один из которых вы использовали для питания cellForRowAtIndexPath: где он должен быть cellForRowAtIndexPath:.

В противном случае код является ошибкой и нестабилен из-за этой связи, поскольку он может указывать на пустой объект

ответил(а) 2021-01-25T15:59:03+03:00 4 месяца, 4 недели назад
44

Проблема здесь:

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

если selectedPeople пуст, и пользователь нажимает на строку 2, тогда он попытается вставить contactInfo в строку 2, которая "выходит за пределы пустого массива". Просто используйте addObject: вместо этого. Вам также нужно будет изменить способ удаления элементов из этого массива (вероятно, лучше использовать словарь).

ответил(а) 2021-01-25T15:59:03+03:00 4 месяца, 4 недели назад
45

Решение добавило идентификатор записи контакта в мой словарь и выполнил поиск с предикатом этого идентификатора контакта. затем удалите его. Достоинства @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);
}

ответил(а) 2021-01-25T15:59:03+03:00 4 месяца, 4 недели назад
-4

Как сказал user2320861, проблема в том, что вы используете insertObject. Я бы сделал следующее:

Измените self.selectedPeople на NSMutableDictionary, используя следующий код:

//in your @interface
@property (nonatomic, strong) NSMutableDictionary *selectedPeople;

Измените код в файле didSelectCellAtIndexPath на:

//Since phone numbers are unique.
self.selectedPeople[cell.contact.numbers.firstObject] = contactInfo;

Извлеките все контакты позже, используя этот код:

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

ответил(а) 2021-01-25T15:59:03+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема