Casting of objects to dynamic types at runtime
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 d开发者_开发百科ynamic 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?
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
.
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:
cell
is just an argument to the method. Reassigningcell
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 thatcell
originally pointed to will continue to point to that original object, blissfully unaware that the method reassigned its argument.- Casting a variable from
ClassA *
toClassB *
does not magically make the underlying data become a instance ofClassB
— 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 theid
type is possible.
精彩评论