无法让Swift使用我的Generic ==运算符

时间:2015-03-31 16:47:17

标签: ios swift core-data

我的应用程序包含许多Core Data NSManagedObject子类,所有子类都有一个我称之为recordID的NSDate。比较两个对象时,我想使用此数据来确定它们是否相同。既然有很多子类,我创建了一个协议来表明它们都实现了一个recordID:

protocol HasID
{
    var recordID: NSDate {get}
}

简单,对吧?现在我已经实现了==运算符,如下所示:

func == <T: HasID>(left: T, right: T) -> Bool
{
    return left.recordID == right.recordID ? true : false
}

问题 - Swift并没有使用我漂亮的==运算符,而是将其与一些通用废话进行比较,如下所示

func ==(lhs: NSObject, rhs: NSObject) -> Bool

现在,如果我为每个子类实现==,如下所示

func == (left: Pilot, right: Pilot) -> Bool
{
    return left.recordID == right.recordID ? true : false
}

然后它使用我的操作员并且工作。 (我还为NSDate实现了一个==运算符,这就是为什么上面的代码没问题。)

我知道如何使用我的泛型==运算符而不是NSObject运算符吗?

2 个答案:

答案 0 :(得分:0)

您可以声明一个中缀运算符:

// I've modified your protocol just for my example

protocol HasID
{
    var recordID: Int {get}
}

infix operator <*> {
    associativity right
}

func <*> (left: HasID, right: HasID) -> Bool
{
    return left.recordID == right.recordID ? true : false
}

// example:

class Fake: HasID {
    var recordID = 1
}

class Bull: HasID {
    var recordID = 1
}

let fake = Fake()
let bull = Bull()
if fake <*> bull {
    println("is equal")
}

答案 1 :(得分:0)

将之前的评论和提案放在一起,似乎是由于NSManagedObject

将以下代码放在游乐场中:

import UIKit
import CoreData

protocol HasID
{
    var recordID: NSDate {get}
}


func == <T: HasID>(left: T, right: T) -> Bool
{
    println("==")
    return left.recordID.isEqualToDate(right.recordID)
}

func ~= <T: NSManagedObject where T: HasID>(left: T, right: T) -> Bool
{
    println("~=")
    return left.recordID.isEqualToDate(right.recordID)
}

class Managed: NSManagedObject, HasID {
    let recordID: NSDate = {
        let components = NSDateComponents()
        components.day = 31
        components.month = 3
        components.year = 2015
        let gregorian = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
        return gregorian.dateFromComponents(components)!
    }()
}

let foo = Managed()
let bar = Managed()

foo == bar
foo ~= bar

switch foo {
case bar:
    println("Equal")
default:
    println("Not Equal")
}

正如您将看到重载 ==永远不会被调用,但~=是。NSManagedObject。 因此,我建议不要过于强迫==使用重载~=并使用switch代替。正如您所看到的,您也可以在NSManagedObject语句中使用它(实际上它是模式匹配运算符)。

如果您从我的示例中删除==,您会发现对于普通的课程,您的解决方案可以正常运行。

我的观点是NSManagedObject的{​​{1}}运算符用于比较托管对象ID,而不是内存中的指针。当相同托管对象存在于不同的托管对象上下文中时,它们可能在内存中具有不同的指针。这就是为什么我不会试图超载它的原因。它有助于在不同的上下文中跟踪相同的托管对象。