Подтвердить что ты не робот

Swift 3 - Как проверить тип класса объекта

Эта строка кода, используемая для работы со Swift 2, но теперь неверна в Swift 3.

if gestureRecognizer.isMember(of: UITapGestureRecognizer) { }

Я получаю эту ошибку: ожидаемое имя участника или вызов конструктора после имени типа.

Каков правильный способ использования isMember(of:)?

4b9b3361

Ответ 1

Скорее всего, вы захотите не только проверить тип, но и применить его к этому типу. В этом случае используйте:

if let gestureRecognizer as? UITapGestureRecognizer { }
else { /* not a UITapGestureRecognizer */ }

Операторы для литья в Swift

Эти операторы доступны только в Swift, но все же работают при работе с типами Objective C.

  • Оператор as

    • Оператор as выполняет литье, когда во время компиляции известно, что приведение всегда выполняется успешно, например, повышение или переключение. Upcasting позволяет использовать выражение как экземпляр супертипа своего типа без использования промежуточной переменной.

    • Это, по возможности, наиболее предпочтительный оператор. Он гарантирует успех, не заботясь о том, чтобы развернуть факультатив или рискнуть сбой.
  • Оператор as?

    • Оператор as? выполняет условное преобразование выражения в указанный тип. Оператор as? возвращает необязательный тип указанного типа. Во время выполнения, если листинг преуспевает, значение выражения заверяется в необязательный и возвращенный; в противном случае возвращаемое значение nil. Если гарантированно завершение или гарантированное завершение выдачи на указанный тип, возникает ошибка времени компиляции.

    • Это второй наиболее предпочтительный оператор для использования. Используйте его, чтобы безопасно обрабатывать случай, в котором оператор литья не может быть выполнен.

  • Оператор as!

    • Оператор as! выполняет принудительное преобразование выражения в указанный тип. Оператор as! возвращает значение указанного типа, а не необязательный тип. Если приведение происходит неудачно, возникает ошибка времени выполнения. Поведение x as! T совпадает с поведением (x as? T)!.

    • Это наименее предпочтительный оператор. Я настоятельно рекомендую не злоупотреблять им. Попытка применить выражение к несовместимому типу приведет к сбою вашей программы.


Собственные методы Swift для проверки типов

Если вы просто хотите проверить тип выражения, не применяя этот тип, вы можете использовать эти подходы. Они доступны только в Swift, но все же работают при работе с типами Objective C.

  • Оператор is

    • Оператор is проверяет во время выполнения, может ли выражение быть передано указанному типу. Он возвращает true, если выражение может быть передано указанному типу; в противном случае он возвращает false
    • Работает с любым типом Swift, включая типы Objective C.
    • Быстрый эквивалент isKind(of:)
  • Использование type(of:)

    • В отличие от оператора is, это может использоваться для проверки точного типа без учета подклассов.
    • Может использоваться как: type(of: instance) == DesiredType.self
    • Быстрый эквивалент isMember(of:)

Объективные методы C для проверки типов

Это все методы на NSObjectProtocol. Они могут использоваться в коде Swift, но они применяют только работу с классами, которые происходят из NSObjectProtocol (например, подклассы NSObject). Я советую не использовать их, но я упоминаю их здесь для полноты

  • isKind(of:)

    • Возвращает логическое значение, указывающее, является ли получатель экземпляром заданного класса или экземпляром любого класса, который наследуется от этого класса
    • Избегайте этого в Swift, используйте вместо этого оператор is.
  • isMember(of:)

    • Возвращает логическое значение, указывающее, является ли получатель экземпляром данного класса
    • Это метод на NSObjectProtocol, поэтому он работает только с классами, которые происходят из NSObjectProtocol (например, подклассы NSObject)
    • Избегайте этого в Swift, вместо этого используйте type(of: instance) == DesiredType.self.
  • conforms(to:)

    • Возвращает логическое значение, указывающее, соответствует ли приемник данному протоколу.
    • Это метод на NSObjectProtocol, поэтому он работает только с классами, которые происходят из NSObjectProtocol (например, подклассы NSObject)
    • Избегайте этого в Swift, используйте вместо этого оператор is.

Ответ 2

Существует несколько способов проверить класс объекта. Большую часть времени вы захотите использовать операторы is или as?, например:

let gestureRecognizer: UIGestureRecognizer = UITapGestureRecognizer()

// Using the is operator
if gestureRecognizer is UITapGestureRecognizer {
    // You know that the object is an instance of UITapGestureRecognizer,
    // but the compiler will not let you use UITapGestureRecognizer specific
    // methods or properties on gestureRecognizer because the type of the
    // variable is still UIGestureRecognizer
    print("Here")
}

// Using the as? operator and optional binding
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer {
    // tapGestureRecognizer is the same object as gestureRecognizer and is
    // of type UITapGestureRecognizer, you can use UITapGestureRecognizer
    // specific methods or properties.
    print("Here")
}

// Using the type(of:) global function
if type(of: gestureRecognizer) == UITapGestureRecognizer.self {
    // gestureRecognizer is an instance of UITapGestureRecognizer, but not any
    // of its subclasses (if gestureRecognizer was an instance of a subclass of
    // UITapGestureRecognizer, the body of this if would not execute).
    // This kind of check is rarely usefull, be sure this is really what you
    // want to do before you use it.
    print("Here")
}

// Using the isKind(of:) method
if gestureRecognizer.isKind(of: UITapGestureRecognizer.self) {
    // Like for the is operator, you know that the object is an instance of
    // UITapGestureRecognizer (or any subclass of UITapGestureRecognizer).
    // This is the Objective-C version of the is operator and will only work
    // on classes that inherit from NSObject, don't use it in Swift.
    print("Here")
}

// Using the isMember(of:) method
if gestureRecognizer.isMember(of: UITapGestureRecognizer.self) {
    // gestureRecognizer is an instance of UITapGestureRecognizer, but not
    // any of its subclasses.
    // This is the Objective-C version of type(of:) and will only work on
    // classes that inherit from NSObject, don't use it in Swift.
    print("Here")
}

Ответ 3

Теперь вы должны использовать .self для обозначения типа класса.

let a = UITapGestureRecognizer()
print (a.isMember(of: UIGestureRecognizer.self))

Существует также:

print (a is UITapGestureRecognizer)

Ответ 4

Swift 3:

if gestureRecognizer is UITapGestureRecognizer {
            //It a tap
}