我的应用程序包含许多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运算符吗?
答案 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,而不是内存中的指针。当相同托管对象存在于不同的托管对象上下文中时,它们可能在内存中具有不同的指针。这就是为什么我不会试图超载它的原因。它有助于在不同的上下文中跟踪相同的托管对象。