Feedback for my solution of the Bronze Challenge


#1

I solved the Bronze Challenge by only adding some code to the ItemsViewController.m - File. My solution works fine, but what do you think, which solution is the most elegant? Some people solved the challenge by creating two additional arrays (below and above 50$) in the model. Is this a better way of handling these tasks? At least I think it would be more reusable compared to my solution.

Thank you very much! :slight_smile:

[code]- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}

  • (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
    if (section == 0)
    return @“Items over 50$”;
    else
    return @“Items below 50$”;

}

  • (NSInteger) tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section
    {

    int counter = 0;

    if (section == 0)
    {
    for (BNRItem *item in [[BNRItemStore sharedStore] allItems]) {

          if ([item valueInDollars] >=50)
              counter++;
      }
    

    } else if (section == 1)
    {
    for (BNRItem *item in [[BNRItemStore sharedStore] allItems]) {

          if ([item valueInDollars] < 50)
              counter++;
      }
    

    }

    return counter;
    }

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell”];

    if (!cell){
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    reuseIdentifier:@“UITableViewCell”];
    }

    NSArray *allItems = [[BNRItemStore sharedStore] allItems];

    switch ([indexPath section]) {

      case 0:
          for (NSInteger i = [indexPath row]; i <= [allItems count]; i++) {
              
              if ([[allItems objectAtIndex:i] valueInDollars] >=50){
                  [[cell textLabel] setText:[[allItems objectAtIndex:i] description]];
                  break;
              }
          }
          break;
          
      case 1:
          for (NSInteger i = [indexPath row]; i <= [allItems count]; i++) {
                      
              if ([[allItems objectAtIndex:i] valueInDollars] < 50){
                  [[cell textLabel] setText:[[allItems objectAtIndex:i] description]];
                  break;
              }
          }
          break;
          
      default:
          break;
    

    }

    return cell;

}[/code]


#2

I am heading in the same direction of leaving the BNRItemStore data alone and having the controller work out the details of how to display the data. I think this is consistent with MVC, but am not sure.

But what I am stuck on is how cell reuse works in this approach. Does your solution allow for cell reuse?


#3

[quote=“DanLoranz”]I am heading in the same direction of leaving the BNRItemStore data alone and having the controller work out the details of how to display the data. I think this is consistent with MVC, but am not sure.

But what I am stuck on is how cell reuse works in this approach. Does your solution allow for cell reuse?[/quote]

Hey Dan!

My approach uses the same type of cell (with the same identifier) for both sections (below and above 50$). Additionally, I did not change the

part. Therefore, I strongly believe that cell reuse is working properly. Whenever a cell moves out of the screen, it can and will be reused for either the first or the second section. However, if you create different cells for both section 1 and section 2 (e.g. cells with different background color), you will need to use two different identifiers for your cells in order to get the right cell type for the current section.

Regarding the MVC problem: I’ve finished a few more chapters since I posted this solution and there was a different design pattern introduced: Model-View-Controller-Store. It is clear, that the Model and the View should not decide what to display at which section. The task of the store is to provide the controller with data (create, destroy, save, load models). The controller decides what to display in which section of the TableView. So maybe the correct design would be like so:

Controller: “ItemStore, I need all items below 50$” ==> Therefore, it would be logical, that the Store would filter the data. Also, it would increase the reusability (“I need all items that have blue color”, “I need all items that are heavy”) etc.

Maybe the best solution is to create more properties in ItemStore in addition to “allItems” (“allGreenItems” / “allHeavyItems” / etc.) ==> Then, additional methods have to be implemented in the Store that can filter the items and fill all the properties.
The controller itself can then focus on his task to decide which data to present and the Store gets this Data for the Controller.

Just my 2 cents, maybe I am totally wrong! :smiley:


#4

Your comments about the Store model make a lot of sense to me. I like it. Thanks for the reply!