2015-03-31 22 views
1

我的應用程序包含許多核心數據NSManagedObject子類,所有這些子類都有一個NSDate,我稱之爲他們的recordID。當比較兩個對象時,我想使用這些數據來確定它們是否相同。現在,因爲有很多子類,我創建了一個協議,表明他們都實現的recordId:不能讓Swift使用我的通用==運算符

protocol HasID 
{ 
    var recordID: NSDate {get} 
} 

簡單,對不對?現在我已經實現了==操作符如下:

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

Problem-斯威夫特不使用我美麗的==操作符,而是使用一些通用的廢話如下

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

如果我實現了現在比較==爲每個單獨的子類如下

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

然後它使用我的操作員和工作。 (我也得到了一個==運算符爲NSDate實現,這就是爲什麼上面的代碼很好。)

任何想法如何讓我的泛型==運算符被使用,而不是NSObject之一?

+0

你是否在類之外聲明瞭==運算符? – 2015-03-31 16:51:35

+0

我不確定,但是對託管對象子類(即使它工作)重寫'=='*可能會成爲一個問題,因爲NSManagedObject文檔明確指出必須重寫'isEqual:'must * absoluty'。 - 我會建議定義一個自定義比較運算符。 – 2015-03-31 16:56:43

+0

你是否符合'Equatable'? – ztan 2015-03-31 17:02:01

回答

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用於比較託管對象ID和內存中的指針。當管理對象存在於不同的管理對象上下文中時,管理對象在內存中可能具有不同的指針。這就是爲什麼我不會試圖超載它。它有助於在不同的上下文中跟蹤相同的管理對象。

+0

可能最後,你會更喜歡一個自定義函數'areEqual'或其他東西,以避免由於'=='和'〜=';-) – 2015-03-31 18:16:44

+0

之間的相似性造成的錯誤嗯,這解決了我的問題。我對NSManagedObject的特殊之處有點困惑,但感謝您的幫助。 – 2015-03-31 21:29:01

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") 
} 
+0

這也解決了我的問題。如果我可以給出兩個綠色的複選標記,但是因爲我不能把它放在下面的一個上,並有更多解釋。感謝您的幫助! – 2015-03-31 21:53:24

+0

沒問題。 Matteo的回答非常好。謝謝。 :) – Moritz 2015-03-31 21:59:18

相關問題