Как избавиться от определенных ячеек TableView

#ios #objective-c #xcode #web-services #uitableview

#iOS #objective-c #xcode #веб-сервисы #uitableview

Вопрос:

Мой tableview заполнен ячейками, в которых отображается элемент с его названием, ценой и брендом. Некоторые объекты, которые я получаю из веб-службы, возвращаются, и это выглядит уродливо в ячейке табличного представления. Я не хочу заполнять ячейки табличного представления, цена которых равна «null». Вот мой код на данный момент. На данный момент я меняю его на «Цена недоступна».

    for (NSDictionary *objItem in resultsArray)
{
     NSString *currentItemName = [objectTitlesArray objectAtIndex:indexPath.row];

    if ([currentItemName isEqualToString:objItem[@"title"]])
    {
        if (cell.priceLabel.text != (id)[NSNull null] amp;amp; cell.priceLabel.text.length != 0 amp;amp; cell.brandLabel.text != (id)[NSNull null] amp;amp; cell.brandLabel.text.length != 0)
        {


        cell.nameLabel.text = currentItemName;

            NSDictionary *bestPageDictionary = objItem[@"best_page"];

            NSNumber *price = bestPageDictionary[@"price"];

            if ((cell.priceLabel.text = @"<null>"))
            {
                cell.priceLabel.text = @"Price Unavailable";
            }

            else
            {

            cell.priceLabel.text = [NSString stringWithFormat:@"$%@", price];
            }


            NSArray *brandsArray = objItem[@"brands"];
        cell.brandLabel.text = [brandsArray firstObject];
        }

    }
}
  

Ответ №1:

Это ужасно неэффективно. Вы сохраняете возврат JSON (я предполагаю) в словаре, а затем перебираете словарь для КАЖДОЙ создаваемой вами ячейки. Мало того, вы не очищаете JSON заранее.

Гораздо дороже создать бесполезную ячейку, а затем вернуться и попытаться удалить ее. В вашем numberOfRowsInSection делегате вы уже сказали tableview , что у вас X много ячеек. Теперь вы пытаетесь удалить ячейки, которые испортят обратные вызовы. Вам нужно будет создать метод, который будет выполняться после завершения создания всех ячеек, который затем будет перебирать все ваши ячейки, чтобы удалить их из TableView, который затем будет вызываться [table reloadData] . Однако, поскольку вы на самом деле не удаляете данные из NSDictionary , вы фактически снова создадите такое же количество ячеек и застрянете в бесконечном цикле.

Решение:

Во-первых, измените свою структуру. Как только вы получите возврат JSON, очистите его, чтобы удалить все значения без цены. Я предлагаю также использовать класс object для хранения каждого объекта сервера. Это значительно упростит ваш код для TableView, а также для других классов. Теперь, когда вы очистили свой возврат, измените его с a NSDictionary на a NSMutableArray . Затем numberOfRowsInSection: вы вызываете [array count] . В cellForRowAtIndexPath: вы просто смотрите [array objectAtIndex:indexPath.row] , чтобы получить свой объект.

Вы хотите, чтобы код в целом выглядел так:

 ServerItem.h : NSObject{
  @property (nonatomic,retain) NSString* name;
  ...
  add in other properties here
}


- (NSMutableArray *) parseJSON:(NSDictionary *)jsonDict{
  NSMutableArray *returnArray = [NSMutableArray array];
  NSArray *dictArray = [NSArray arrayWithArray:jsonDict[@"results"]];
  for (NSDictionary *itemDict in dictArray)
  {
    NSDictionary *bestPageDictionary = objItem[@"best_page"];
    if (![bestPageDictionary[@"price"] isEqualToString:@"<null>"]])
    {
      ServerItem item = [ServerItem new];
      item.price = ...
      item.name = ....
      [returnArray addObject:item];
    }       
  }
  return returnArray;
}
  

Внутри вашего кода веб-сервиса:

 self.itemArray = [self parseJSON:dataDictionary];
  

Затем

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.itemCallArray count]    
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  ServerItem *cellItem = [self.itemsArray objectAtIndex:indexPath.row];
  cell.nameLabel.text = cellItem.name;
  cell.priceLabel.text = cellItem.price;
  ...

}
  

Комментарии:

1. Итак, я создаю метод перед numberOfRowsInSection с циклом for, который проходит через все мои ячейки и возвращает только ячейки с ценой?

2. Извините, но, возможно, я мог бы увидеть пример кода, чтобы начать работу?

3. Нет — когда вы получите возврат веб-службы, выполните цикл через NSDictionary, чтобы удалить из него все плохие объекты. Вы хотите очистить свои данные, прежде чем пытаться создавать ячейки. Суть в том, что вы никогда не должны удалять ячейки из-за неверных данных. Опубликуйте код синтаксического анализа возврата вашего веб-сервиса.

4. Дайте мне знать, имеет ли смысл то, что я опубликовал — это требует от вас реструктуризации вашего кода, но это сделает его намного более чистым, эффективным, читаемым и объектно-ориентированным. Он знакомит вас с использованием объекта ServerItem для хранения вашего возврата с сервера. Теперь вам не нужно хранить массив заголовков элементов, а затем анализировать ячейки на лету. У вас есть предварительный синтаксический анализ, после чего все создается / сортируется для вас в массив ServerItems . Затем, когда вы создаете ячейки, очень легко получить доступ к каждой из них и их свойствам.

5. Итак, метод parseJSON выполняется после вызова? но тогда как мне получить массив данных, если я делаю это вне вызова