Question Égalité personnalisée dans les objets rapides préservant la compatibilité avec le code Objective-C hérité


En Objective-C, vous feriez quelque chose comme

- (BOOL)isEqual:(id)other {
    if (other == self)
        return YES;
    if (!other || ![other isKindOfClass:[self class]])
        return NO;
    return [self.customProperty isEqual:other.customProperty];
}

Ma première tentative naïve en swift se déroule comme suit

func isEqual(other: AnyObject) -> Boolean {
    if self === other {
        return true
    }
    if let otherTyped = other as? MyType {
        return self.myProperty == otherTyper.myProperty
    }
    return false
}

Mais je suis loin d’être heureux avec ça. Je ne sais même pas si la signature est correcte ou si nous sommes censés utiliser autre chose que isEqual.

Des pensées?

MODIFIER: Je souhaite également conserver la compatibilité Objective-C (ma classe est utilisée à la fois dans le code Obj-C hérité et dans le nouveau code Swift). Donc, je pense que la priorité == n'est pas suffisant. Ai-je tort?


35
2018-06-03 18:58


origine


Réponses:


Oui, vous devez remplacer isEqual (et hash) pour rendre vos objets entièrement compatibles avec Objective-C. Voici un exemple prêt pour Playground pour la syntaxe:

import Foundation

class MyClass: NSObject {

    var value = 5

    override func isEqual(object: AnyObject?) -> Bool {
        if let object = object as? MyClass {
            return value == object.value
        } else {
            return false
        }
    }

    override var hash: Int {
        return value.hashValue
    }
}

var x = MyClass()
var y = MyClass()
var set = NSMutableSet()

x.value = 10
y.value = 10
set.addObject(x)

x.isEqual(y) // true
set.containsObject(y) // true

(courant de syntaxe à partir de Xcode 6.3)


61
2017-10-14 19:44



Vous pouvez également implémenter un équalisable personnalisé, par exemple:

func == (lhs: CustomClass, rhs: CustomClass) -> Bool {
     return lhs.variable == rhs.variable
}

Cela vous permettra de vérifier simplement l'égalité comme ceci:

let c1: CustomClass = CustomClass(5)
let c2: CustomClass = CustomClass(5)

if c1 == c2 { 
    // do whatever
}

Assurez-vous que votre équateur personnalisé est hors de portée de la classe!


8
2018-05-12 14:51



Dans Swift, vous pouvez remplacer les opérateurs infixes (et même créer les vôtres). Voir ici.

Donc, plutôt que d'utiliser isEqual, vous pouvez faire:

myType == anotherType

2
2018-06-03 19:01



Et (bien sûr) la signature a juste dû changer pour swift3:

open override func isEqual(_ object: Any?) -> Bool {
    guard let site = object as? PZSite else {
        return false
    }
....
}

1
2017-08-15 09:48



Pour archiver la compatibilité Objective-C, vous devez remplacer la méthode isEqual décrite à la page 16 de ce document: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/BuildingCocoaApps.pdf 


0
2018-06-06 11:52