Как проверить класс переменной в Swift?

Я хочу проверить, являются ли элементы массива подклассом UILabel в Swift:

import UIKit

var u1 = UILabel()
u1.text="hello"
var u2 = UIView(frame: CGRectMake(0, 0, 200, 20))
var u3 = UITableView(frame: CGRectMake(0, 20, 200, 80))

var myArray = [u1, u2, u3]

var onlyUILabels = myArray.filter({"what to put here?"})

Без перехода на objective-c.

Ответ 1

Swift имеет оператор is для проверки типа значения:

var onlyUILabels = myArray.filter { $0 is UILabel }

Как побочная заметка, это все равно приведет к Array<UIView>, а не Array<UILabel>. Начиная с бета-серии Swift 2, вы можете использовать flatMap для этого:

var onlyUILabels = myArray.flatMap { $0 as? UILabel }

Раньше (Swift 1), вы можете накладывать, что работает, но чувствует себя немного уродливо.

var onlyUILabels = myArray.filter { $0 is UILabel } as! Array<UILabel>

Или вам нужно каким-то образом создать список только ярлыков. Я не вижу ничего стандартного. Может быть, что-то вроде:

extension Array {
    func mapOptional<U>(f: (T -> U?)) -> Array<U> {
        var result = Array<U>()
        for original in self {
            let transformed: U? = f(original)
            if let transformed = transformed {
                result.append(transformed)
            }
        }
        return result
    }
}
var onlyUILabels = myArray.mapOptional { $0 as? UILabel }

Ответ 2

В Swift вы должны сделать ключевое слово is, если вам интересно узнать о соответствующем классе. В filter -closure вы можете использовать $0 для указания первого параметра.

Пример

var (a,b,c,d) = ("String", 42, 10.0, "secondString")
let myArray: Array<Any> = [a,b,c,d]
var onlyStrings = myArray.filter({ return $0 is String })
onlyStrings // ["String", "secondString"]

Ответ 3

Не доходя до объекта object.class() nirvana, в Swift мы все равно можем использовать Objective-C Runtime, чтобы получить полезную информацию о классе объекта следующим образом (и не точно перейдем к Objective-C):

let objectClass: AnyClass = object_getClass(object) as AnyClass
let objectClassName =  NSStringFromClass(objectClass)
println("Class = \(objectClassName)")

Обратите внимание, что мы получаем "MyProject". или (иногда) "Свифт". префикс, в зависимости от того, ссылаетесь ли вы на свои классы или классы Swift:

UILabel // UILabel    
Swift._NSSwiftArrayImpl //Swift Array
MyProject.Customer_Customer_   //for a CoreData class named Customer

Ответ 4

Вы можете сравнить классы, используя следующее в swift:

 return object.dynamicType == otherObject.dynamicType

dynamicType вернет экземпляр класса, который вы можете сравнить