2016-01-03 8 views
5

のEquatable機能を呼び出すことはありません - objectIdsとをこのように比較するためのEquatable機能の実装とMYUSERクラス:スウィフトArray.contains()私は<strong>PFUser</strong>のサブクラス持っPFUserサブクラス

func ==(left: MYUser, right: MYUser) -> Bool { 
    return left.objectId == right.objectId 
} 

しかし、Array.contains()メソッドを呼び出すと、この実装はEquatable関数と呼ばれ、誤った結果につながります。例えば、ここに:

let hasUser = self.selectedUsers.contains(currentUser) 

hasUser場合selectedUsersが配列が異なるメモリオブジェクトが含まれていますが、あるCurrentUserと同じOBJECTIDとなりました。

興味深いことに、Equatable関数の実装が直接使用されています。ここでは:正常に呼び出されました

var hasUser = false 
for itUser in self.selectedUsers { 
    if itUser == currentUser { 
    hasUser = true 
    break 
    } 
} 

==オペレータとが異なるメモリオブジェクトのためのそれの原因となることができますどのような同じOBJECTID

と正しい値を持っているhasUser?

更新。私はこのNSObject問題だと思う

class MYUser: PFUser { 

    // MARK: - Parse Object 

    @NSManaged var avatarFile: PFFile? 
    @NSManaged var fullName: String? 

    // MARK: - PFSubclassing Methods (through PFUser) 

    override class func initialize() { 
     struct Static { 
      static var onceToken : dispatch_once_t = 0; 
     } 
     dispatch_once(&Static.onceToken) { 
      self.registerSubclass() 
     } 
    } 
} 

func ==(left: MYUser, right: MYUser) -> Bool { 
    return left.objectId == right.objectId 
} 
+1

私はParse.com経験がないが、これは関連している可能性があり:http://stackoverflow.com/questions/33319959/nsobject-subclass-in-swift-hash-vs-hashvalue-isequal-vs - '=='ではなく 'isEqual:'をオーバーライドしてみてください。 –

+0

@MartinR ParseとObjCの相互運用性は唯一の問題ではないと思います。純粋なSwift MWEを作成し、サブクラスの '=='のオーバーロードは 'contains'で呼び出されません。 –

+0

それは関係ないかもしれませんが、あなたは私のMYUserがどのように定義されているかを見せてもらえますか? –

答えて

9

: はここにMYUSERクラスです。

class MYUserNSObject: NSObject { 
    dynamic var fullName: String 

    init(fullName: String) { 
     self.fullName = fullName 
     super.init() 
    } 
} 

func ==(left: MYUserNSObject, right: MYUserNSObject) -> Bool { 
    return left.fullName == right.fullName 
} 

let objectUsers = [MYUserNSObject(fullName: "a"), MYUserNSObject(fullName: "b")] 
let objectResult = objectUsers.contains(MYUserNSObject(fullName: "a")) 
print("\(result)") 

falseを出力します。

class MYUserSwift: Equatable { 
    var fullName: String 

    init(fullName: String) { 
     self.fullName = fullName 
    } 
} 

func ==(left: MYUserSwift, right: MYUserSwift) -> Bool { 
    return left.fullName == right.fullName 
} 

let swiftUsers = [MYUserSwift(fullName: "a"), MYUserSwift(fullName: "b")] 
let swiftResult = swiftUsers.contains(MYUserSwift(fullName: "a")) 
print("\(swiftResult)") 

Prints true。


最後に、-isEqual:を追加することで、これを修正しました。

class MYUserNSObject: NSObject { 
    dynamic var fullName: String 

    init(fullName: String) { 
     self.fullName = fullName 
     super.init() 
    } 

    override func isEqual(object: AnyObject?) -> Bool { 
     guard let user = object as? MYUserNSObject else { return false } 
     return self == user 
    } 
} 

func ==(left: MYUserNSObject, right: MYUserNSObject) -> Bool { 
    return left.fullName == right.fullName 
} 

let objectUsers = [MYUserNSObject(fullName: "a"), MYUserNSObject(fullName: "b")] 
let objectResult = objectUsers.contains(MYUserNSObject(fullName: "a")) 
print("\(objectResult)") 

trueを出力します。真スウィフト4.0

class MYUserNSObject: NSObject { 
    @objc var fullName: String 

    init(fullName: String) { 
     self.fullName = fullName 
     super.init() 
    } 

    override func isEqual(_ object: Any?) -> Bool { 
     guard let user = object as? MYUserNSObject else { return false } 
     return self.fullName == user.fullName 
    } 
} 

let objectUsers = [MYUserNSObject(fullName: "a"), MYUserNSObject(fullName: "b")] 
let objectResult = objectUsers.contains(MYUserNSObject(fullName: "a")) 
print("\(objectResult)") 

プリント用に更新


注:==(left:right:)機能は必要なくなりました。

let success = MYUserNSObject(fullName: "a") == objectUsers[0] 
print("success should be true: \(success)") 

let failure = MYUserNSObject(fullName: "a") == objectUsers[1] 
print("failure should be false: \(failure)") 
+1

はい、Array.contains()はNSObjectサブクラスのために特別に '-isEquals:'メソッドを呼び出すようです。ありがとうございました。 –

+0

Hee Jeffrey、解決策を提供してくれてありがとう。これは私に非常に多くの時間を節約しました。これは、==演算子のオーバーロードを使用して2つのカスタムクラスを比較する最良の答えです。もう一度ありがとう:) –

+0

最新のSwiftのアップデート、isEqualのプロトタイプは "Any?"です。 「AnyObject」ではない –

関連する問題