Monday, May 15, 2017

Searching for Swift Objects by Type

Tim Ekl:

This rubbed me the wrong way, specifically because of the is SpecialView/as! SpecialView combination. It seemed like I should be able to do the type check once and get the object back as that type, maybe using as?.

[…]

However, there’s a cost here: where previously we’d stop enumerating subviews once we found the first SpecialView, with flatMap we run all the way through the array before getting the first result. If subviews is an especially large array, this could become a performance hotspot very quickly.

In Objective-C, the obvious for loop or array-searching closure would do the right thing, without the need for concepts like flatMap and lazy. Then again, so would a Swift for loop with if let, but people would tend not to write it that way.

If you wanted to generalize this sort of view search in Objective-C, you could pass a class as a parameter. That doesn’t really work in Swift because you would end up with an awkward Any? return value. So you get into generics. You can pass a parameter of type Any.Type, but that doesn't really help because Swift can’t use this to determine the return type. Instead, you could make the function take no parameters, passing the type as a generic parameter that’s inferred based on the calling context. However, I think that makes the call sites look weird, and you still end up with an optional to unwrap.

1 Comment RSS · Twitter

The best syntax for this is for case let [name] as [type] in [collection]. ;-)

var specialView: SpecialView? {
    for case let subview as SpecialView in subviews {
        return childElement
    }
    return nil
}

Leave a Comment