web-dev-qa-db-ja.com

Swiftレガシー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];
}

Swift=

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

しかし、私はそれで満足しているわけではありません。署名が正しいかどうか、またはisEqual以外の何かを使用することになっているかどうかもわかりません。

何かご意見は?

編集:Objective-Cとの互換性も維持したい(私のクラスはレガシーObj-Cコードと新しいSwiftコード)の両方で使用されています。したがって、==だけでは十分ではありません。私が間違っている?

40

はい、Objective-Cと完全に互換性を持たせるには、isEqual(およびhash)をオーバーライドする必要があります。構文のPlayground対応の例を次に示します。

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現在の構文)

68
nschum

たとえば、カスタム赤道を実装することもできます。

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
}

カスタム赤道がクラス範囲外であることを確認してください!

9
Gregg

Swift3 sig:

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

Swiftでは、中置演算子をオーバーライドできます(独自に作成することもできます)。 here を参照してください。

したがって、isEqualを使用する代わりに、次のことを実行できます。

myType == anotherType
1
gwcoffey

Objective-Cの互換性をアーカイブするには、このドキュメントの16ページに記載されているisEqualメソッドをオーバーライドする必要があります。 https://developer.Apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/BuildingCocoaApps .pdf

0

もう一つの例

public class PRSize: NSObject {

    public var width: Int
    public var height: Int

    public init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }

    static func == (lhs: PRSize, rhs: PRSize) -> Bool {
        return lhs.width == rhs.width && lhs.height == rhs.height
    }

    override public func isEqual(_ object: Any?) -> Bool {

        if let other = object as? PRSize {
            if self === other {
                return true
            } else {
                return self.width == other.width && self.height == other.height
            }
        }

        return false

    }

    override public var hash : Int {
        return "\(width)x\(height)".hashValue
    }

}
0
yoAlex5