1

I have a nib containing a bunch of UITableCellViews all derived from a class called MessageCell. These custom classes are in Objective C and I have bridged them into my Swift project.

I'd like to be able to fetch one of interest. I tried this function

func cellTypeFromNib<T>(type : T) -> MessageCell? {
    var cell : MessageCell? = nil
    for obj in self.nibObjs {
        if (obj is T) {
            return obj as? MessageCell
        }
    }
    return cell     
}

and invoke it like this:

let cell = cellTypeFromNib(DerivedCell.self)?

This fails miserably. Stepping through the debugger, it looks like the objects in nibObjs don't have the same type information as the metatype I've passed in.

I feel like this should be possible but I'm stumped.

MattD
  • 380
  • 1
  • 15

2 Answers2

0

Through sheer force of will I solved this.

The correct declaration is as follows

func cellTypeFromNib<T>(type : T.Type) -> MessageCell? {
 for obj in self.nibObjs {
    if (obj is T) {
        return obj as? MessageCell
    }
 }
 return nil     
}

The secret is .Type on the template parameter. I would love some guidance on why but I'll settle for the how.

EDIT: removed extraneous local variable

MattD
  • 380
  • 1
  • 15
0

Your answer is correct, but you should constrain T as MessageCell:

func cellTypeFromNib<T: MessageCell>(type : T.Type) -> MessageCell? {
    for obj in self.nibObjs {
        if let cell = obj as? T {
            return cell
        }
    }
    return nil
}

<T: MessageCell> ensures cell is MessageCell at compile time. This prevents someone accidentally call it like let cell = cellTypeFromNib(UnrelatedClass.self)

rintaro
  • 51,423
  • 14
  • 131
  • 139
  • I don't know if it applies here, but I had an issue where optional casting + optional binding did not work as expected: http://stackoverflow.com/questions/25838032/optional-binding-succeeds-if-it-shouldnt. In that case, *removing* the type constraint was one method to work around that problem/bug. – Martin R Feb 06 '15 at 13:10
  • I had the same problem as Martin R - I got a false positive when constraining T to the base type. Type inheritance should mirror value inheritance, so this might be a bug. – MattD Feb 06 '15 at 14:55