Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 162 Vote(s) - 3.68 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to check two instances are the same class/type in swift

#1
I know that I can check the type of a var in Swift with `is`

if item is Movie {
movieCount += 1
} else if item is Song {
songCount += 1
}

but how can I check that two instances have the same class? The following does not work:

if item1 is item2.dynamicType {
print("Same subclass")
} else {
print("Different subclass)
}

I could easily add a "class" function and update it in each subclass to return something unique, but that seems like a kludge...
Reply

#2
In Swift 5 you can test whether one value is the same type as another, if one of the values is 'self', by using 'Self', its type. This works with structs, as you can see below.

(I am actually here looking for a way to do this without Self as I am trying to refactor something. The 'type(of: ship)' method mentioned above, looks like the most general way to do this. I have tested that it works with the example below.)

protocol Ship { var name: String {get} }

extension Ship {
func isSameClass(as other: Ship) -> Bool {
return other is Self
}
}

struct Firefly: Ship { var name: String }
struct Trebuchet: Ship { var name: String }

func speak(about s1: Ship, and s2: Ship) {
print( "\(s1.name) and \(s2.name) are "
+ "\(s1.isSameClass(as: s2) ? "" : "not ")"
+ "the same class." )
}

func talk(about s1: Ship, and s2: Ship) {
print( "\(s1.name) and \(s2.name) are "
+ "\(type(of: s1) == type(of: s2) ? "" : "not ")"
+ "the same class." )
}

var serenity = Firefly(name: "Serenity")
var saffron = Firefly(name: "Saffron")
var inara = Trebuchet(name: "Inara")

speak(about: serenity, and: saffron) // Serenity and Saffron are the same class.
speak(about: serenity, and: inara) // Serenity and Inara are not the same class.
talk(about: serenity, and: saffron) // Serenity and Saffron are the same class.
talk(about: serenity, and: inara) // Serenity and Inara are not the same class.
Reply

#3
For subclasses of `NSObject`, I went with:

let sameClass: Bool = instance1.classForCoder == instance2.classForCoder

Another caveat of this method,

> The private subclasses of a class cluster substitute the name of their public superclass when being archived.

[Apple documentation][1]


[1]:

[To see links please register here]

Reply

#4
i'm using this, looks helpful for me:
it returns `true` only if all objects are of same type;

func areObjects<T>(_ objects: [Any], ofType: T.Type) -> Bool {
for object in objects {
if !(object is T) {
return false
}
}
return true
}
Reply

#5
I feel necessary to quote from the _Swift Programming Language_ documentation first of all:

> Classes have additional capabilities that **structures do not**:

> - Type casting enables you to check and interpret the type of a class instance at runtime.

---

According to this, it may be helpful for someone in the future:

func areTheySiblings(class1: AnyObject!, class2: AnyObject!) -> Bool {
return object_getClassName(class1) == object_getClassName(class2)
}

---

and the tests:

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

---

#UPDATE

you also can overload a new operator for doing such a thing, like e.g. this:

infix operator >!<

func >!< (object1: AnyObject!, object2: AnyObject!) -> Bool {
return (object_getClassName(object1) == object_getClassName(object2))
}

and the results:

println("Array vs Array: \(myArray1 >!< myArray2)") // true
println("Array vs. String: \(myArray1 >!< myString)") // false
println("Array vs. Dictionary: \(myArray1 >!< myDictionary)") // false

#UPDATE#2

you can also use it for your own new _Swift_ classes, like e.g. those:

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
Reply

#6
Swift 3
- pay attention that comparing instances is not the same as checking if an istance is of a given type:

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

Reply

#7
Swift 3.0 (also works with structs)

if type(of: someInstance) == type(of: anotherInstance) {
print("matching type")
} else {
print("something else")
}
Reply

#8
I also answered

[To see links please register here]

to point out that at some point Apple added support for the `===` operator to Swift Types, so the following will now work:

if item1.dynamicType === item2.dynamicType {
print("Same subclass")
} else {
print("Different subclass")
}

This works even without importing `Foundation`, but note _it will only work for classes_, as `structs` have no dynamic type.
Reply

#9
At the moment Swift types have no introspection, so there is no builtin way to get the type of an instance. `instance.className` works for Objc classes.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through