2015-05-07 15 views
5

Data la classe seguente, come possono essere confrontati tutti i valori in due istanze l'uno con l'altro?Confronta due istanze di un oggetto in Swift

// Client Object 
// 
class PLClient { 
    var name = String() 
    var id = String() 
    var email = String() 
    var mobile = String() 
    var companyId = String() 
    var companyName = String() 

    convenience init (copyFrom: PLClient) { 
     self.init() 
     self.name = copyFrom.name 
     self.email = copyFrom.email 
     self.mobile = copyFrom.mobile 
     self.companyId = copyFrom.companyId 
     self.companyName = copyFrom.companyName 

    } 

} 

var clientOne = PLClient() 

var clientTwo = PLClient(copyFrom: clientOne) 

if clientOne == clientTwo { // Binary operator "==" cannot be applied to two PLClient operands 
    println("No changes made") 
} else { 
    println("Changes made. Updating server.") 
} 

Il caso d'uso per questo è in un'applicazione che presenta i dati da un server. Una volta che i dati vengono convertiti in un oggetto, viene creata una copia dell'oggetto. L'utente è in grado di modificare vari campi ecc. Che cambia i valori in uno degli oggetti.

L'oggetto principale, che potrebbe essere stato aggiornato, deve essere confrontato con la copia di tale oggetto. Se gli oggetti sono uguali (i valori di tutte le proprietà sono uguali), non succede nulla. Se uno qualsiasi dei valori non è uguale, l'applicazione invia le modifiche al server.

Come mostrato nell'esempio di codice, l'operatore == non viene accettato perché non viene specificato un valore. L'utilizzo di === non consente di ottenere il risultato desiderato poiché queste saranno sempre due istanze separate.

+1

sovraccarico '==' per la tua classe. – dasdom

+2

Conformandosi a [Equatable] (https://developer.apple.com/library/ios/documentation/General/Reference/SwiftStandardLibraryReference/Equatable.html) – Alladinian

risposta

23

Indicare che la classe è conforme al protocollo Equabile e quindi implementare l'operatore ==.

Qualcosa di simile a questo:

class PLClient: Equatable 
{ 
    var name = String() 
    var id = String() 
    var email = String() 
    var mobile = String() 
    var companyId = String() 
    var companyName = String() 
    //The rest of your class code goes here 

    public static func ==(lhs: PLClient, rhs: PLClient) -> Bool{ 
     return 
      lhs.name == rhs.name && 
      lhs.id == rhs.id && 
      lhs.email == rhs.email && 
      lhs.mobile == rhs.mobile && 
      lhs.companyId == rhs.companyId && 
      lhs.companyName == rhs.companyName 
    } 
} 
5

Lavorare fuori della risposta di Duncan C, sono venuto su con un'alternativa che è un po 'più chiaro che viene utilizzato in modo personalizzato:

// Client Object 
// 
class PLClient { 
    var name = String() 
    var id = String() 
    var email = String() 
    var mobile = String() 
    var companyId = String() 
    var companyName = String() 

    convenience init (copyFrom: PLClient) { 
     self.init() 
     self.name = copyFrom.name 
     self.email = copyFrom.email 
     self.mobile = copyFrom.mobile 
     self.companyId = copyFrom.companyId 
     self.companyName = copyFrom.companyName 
    } 

    func equals (compareTo:PLClient) -> Bool { 
     return 
      self.name == compareTo.name && 
      self.email == compareTo.email && 
      self.mobile == compareTo.mobile 
    } 

} 

var clientOne = PLClient() 
var clientTwo = PLClient(copyFrom: clientOne) 

if clientOne.equals(clientTwo) { 
    println("No changes made") 
} else { 
    println("Changes made. Updating server.") 
} 
+0

c'è un caso per scrivere un metodo di confronto con la firma equivalente di " è uguale a:" ? – Damo

+0

Se si desidera, è possibile chiamare il metodo comparatore "fred". Non conosco nessun uso del sistema con quel nome, quindi dipende da te. Penso che "isEqualTo" mostri molto bene l'intento del metodo, quindi sarebbe una buona scelta. –

+0

In Swift, il modo corretto di implementare un test di uguaglianza è una classe o una struttura che deve essere conforme al protocollo Equatable. Non riesco a vedere alcun motivo per implementare una funzione come "isEqualTo:" in particolare poiché la classe potrebbe essere estesa in seguito per conformarsi al protocollo Equality e quindi avere due test di uguaglianza potenzialmente diversi. Inoltre, un metodo "isEqualTo:" potrebbe essere sovrascritto da una sottoclasse. Questa sarebbe una brutta cosa perché rompe la regola "sottoclasse di A è una A". La funzione di protocollo == Equality non può essere sovrascritta da una sottoclasse. –