views:

42

answers:

2

I have the following code:

+ (UITableViewCell *) createTableViewCell: (NSString *) cell_id withTableView: tableView {
  SomeViewClass *cell = (SomeViewClass *)[tableView dequeueReusableCellWithIdentifier: cell_id];

  if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed: @"AViewCell"
                                                             owner: nil
                                                           options: nil];


    for (id currentObject in topLevelObjects) {
      if ([currentObject isKindOfClass: [UITableViewCell class]]) {
        cell = (SomeViewClass *) currentObject;
        break;
      }
    }
  }

  return cell;
}

I'd like to abstract that code so that it can be used with any view class, not just a "SomeViewClass". I'd like to transform it into something like the following. Notice the cast of the dynamic type (a class *) below.

+ (UITableViewCell *) createTableViewCell: (NSString *) cell_id withTableView: tableView withClass: (Class) a_class {
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cell_id];

  if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed: @"AViewCell"
                                                             owner: nil
                                                           options: nil];


    for (id currentObject in topLevelObjects) {
      if ([currentObject isKindOfClass: [UITableViewCell class]]) {
        cell = (a_class *) currentObject;
        break;
      }
    }
  }

  return cell;
}

That raises a compile time error. Do I have to resort to macros? Is there a better way to do this?

+1  A: 

What if you just cast it to UITableViewCell?

for (id currentObject in topLevelObjects) {
    if ([currentObject isKindOfClass: [UITableViewCell class]]) {
        cell = (UITableViewCell *) currentObject;
        break;
    }
}

That shouldn't cause any error (compile or run-time) as long as a_class inherits UITableViewCell.

Josh Hinman
+1  A: 

There is no point whatsoever in what you're trying to do, even if it were possible. That cast does not change the object, for two reasons:

  1. cell is just an argument to the method. Reassigning cell to point to something else merely makes the argument point to a different object; it doesn't cause anything else in the program to change. In particular, other references to the object that cell originally pointed to will continue to point to that original object, blissfully unaware that the method reassigned its argument.
  2. Casting a variable from ClassA * to ClassB * does not magically make the underlying data become a instance of ClassB — it just lies to the compiler about what kind of object the variable is pointing to. The object's class is an attribute of the object itself — that's why the id type is possible.
Chuck