protocolos - que es self en swift
Cómo verificar dos instancias son de la misma clase/tipo en swift (7)
En primer lugar, creo necesario citar de la documentación de Swift Programming Language :
Las clases tienen capacidades adicionales que las estructuras no :
- La conversión de tipos le permite verificar e interpretar el tipo de una instancia de clase en tiempo de ejecución.
De acuerdo con esto, puede ser útil para alguien en el futuro:
func areTheySiblings(class1: AnyObject!, class2: AnyObject!) -> Bool {
return object_getClassName(class1) == object_getClassName(class2)
}
y las pruebas:
let myArray1: Array<AnyObject> = Array()
let myArray2: Array<Int> = Array()
let myDictionary: Dictionary<String, Int> = Dictionary()
let myString: String = String()
let arrayAndArray: Bool = self.areTheySiblings(myArray1, class2: myArray2) // true
let arrayAndString: Bool = self.areTheySiblings(myArray1, class2: myString) // false
let arrayAndDictionary: Bool = self.areTheySiblings(myArray1, class2: myDictionary) // false
ACTUALIZAR
también puede sobrecargar un nuevo operador por hacer tal cosa, como por ejemplo esto:
infix operator >!<
func >!< (object1: AnyObject!, object2: AnyObject!) -> Bool {
return (object_getClassName(object1) == object_getClassName(object2))
}
y los resultados:
println("Array vs Array: /(myArray1 >!< myArray2)") // true
println("Array vs. String: /(myArray1 >!< myString)") // false
println("Array vs. Dictionary: /(myArray1 >!< myDictionary)") // false
ACTUALIZACIÓN # 2
también puede usarlo para sus propias clases de Swift , como por ejemplo:
class A { }
class B { }
let a1 = A(), a2 = A(), b = B()
println("a1 vs. a2: /(a1 >!< a2)") // true
println("a1 vs. b: /(a1 >!< b)") // false
Sé que puedo verificar el tipo de var en Swift con
if item is Movie {
movieCount += 1
} else if item is Song {
songCount += 1
}
pero ¿cómo puedo verificar que dos instancias tengan la misma clase? Lo siguiente no funciona:
if item1 is item2.dynamicType {
print("Same subclass")
} else {
print("Different subclass)
}
Podría agregar fácilmente una función de "clase" y actualizarla en cada subclase para devolver algo único, pero eso parece un error ...
Estoy usando esto, me parece útil: devuelve true
solo si todos los objetos son del mismo tipo;
func areObjects<T>(_ objects: [Any], ofType: T.Type) -> Bool {
for object in objects {
if !(object is T) {
return false
}
}
return true
}
Para las subclases de NSObject
, fui con:
let sameClass: Bool = instance1.classForCoder == instance2.classForCoder
Otra advertencia de este método,
Las subclases privadas de un clúster de clase sustituyen el nombre de su superclase pública cuando se archivan.
Por el momento, los tipos Swift no tienen introspección, por lo que no existe una forma integrada de obtener el tipo de instancia. instance.className
funciona para las clases Objc.
Swift 3.0 (también funciona con estructuras)
if type(of: someInstance) == type(of: anotherInstance) {
print("matching type")
} else {
print("something else")
}
Swift 3: preste atención a que comparar instancias no es lo mismo que verificar si una istance es de un tipo dado:
struct Model {}
let modelLhs = Model()
let modelRhs = Model()
type(of: modelLhs) == type(of: modelRhs) //true
type(of: modelLhs) == type(of: Model.self) //false
modelLhs is Model //true
También respondí ¿Cómo averiguas el tipo de objeto (en Swift)? para señalar que en algún punto, Apple agregó soporte para el operador ===
a Swift Types, entonces lo siguiente ahora funcionará:
if item1.dynamicType === item2.dynamicType {
print("Same subclass")
} else {
print("Different subclass")
}
Esto funciona incluso sin importar Foundation
, pero tenga en cuenta que solo funcionará para las clases , ya que las structs
no tienen un tipo dinámico.