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

Пользовательское равенство в быстрых объектах, сохраняющее совместимость с устаревшим кодом Objective-C

В Objective-C вы делаете что-то в строках

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

Моя первая наивная попытка в быстрой последовательности выглядит следующим образом

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

Но я далеко не доволен этим. Я даже не знаю, правильна ли подпись или мы должны использовать что-либо другое, чем isEqual.

Любые мысли?

EDIT: Я также хотел бы сохранить совместимость Objective-C (мой класс используется как в устаревшем коде Obj-C, так и в новом коде Swift). Поэтому я думаю, что переопределения == недостаточно. Я не прав?

4b9b3361

Ответ 1

Да, вы должны переопределить isEqualhash), чтобы ваши объекты полностью совместимы Objective-C. Здесь представлен пример для синтаксиса:

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

(синтаксический ток с Xcode 6.3)

Ответ 2

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

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

Это позволит вам просто проверить равенство следующим образом:

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

if c1 == c2 { 
    // do whatever
}

Убедитесь, что ваш пользовательский эквивалент находится за пределами класса!

Ответ 3

swift3 sig:

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

Ответ 4

В Swift вы можете переопределить операторы infix (и даже сделать свой собственный). См. здесь.

Поэтому вместо использования isEqual вы можете сделать:

myType == anotherType