2014-09-07 14 views
86

In Swift, qual è il modo convenzionale per definire il modello comune in cui una proprietà deve essere esternamente in sola lettura, ma modificabile internamente dalla classe (e sottoclassi) che lo possiede.Swift di sola lettura esterna, proprietà di lettura interna

in Objective-C, vi sono le seguenti opzioni:

  • dichiarare la proprietà come sola lettura nell'interfaccia e utilizzare un'estensione di classe per accedere alla proprietà internamente. Questo è l'accesso basato sui messaggi, quindi funziona bene con KVO, atomicità, ecc.
  • Dichiarare la proprietà come readonly nell'interfaccia, ma accedere internamente al supporto di ivar. Poiché l'accesso predefinito per un ivar è protetto, questo funziona bene in una gerarchia di classi, in cui le sottoclassi saranno anche in grado di modificare il valore, ma il campo è altrimenti in sola lettura.

In Java la convenzione è:

  • dichiarare un campo di protezione, e implementare un pubblico, di sola lettura getter (metodo).

Qual è l'idioma per Swift?

+0

grande domanda! Grazie. Molto ben scritto – SuperDuperApps

risposta

170

Data una proprietà di classe, è possibile specificare un diverso livello di accesso mediante il prefisso della dichiarazione di proprietà con il modificatore di accesso seguito da get o set tra parentesi. Ad esempio, una proprietà di classe con un getter pubblico e un setter privato sarà dichiarato come:

private(set) public var readonlyProperty: Int 

Lettura consigliata: Getters and Setters

considerazioni di Martin circa livello di accessibilità sono ancora valide - vale a dire non c'è protected modificatore, internal limita l'accesso solo al modulo, private solo al file corrente e public senza restrizioni.

Swift 3 note

2 nuovi modificatori di accesso, fileprivate e open sono stati aggiunti al linguaggio, mentre private e public sono state leggermente modificate:

  • open vale per i soli membri della classe e di classe : è usato per consentire a una classe di essere sottoclassata o un membro per essere sovrascritto al di fuori del modulo in cui sono definiti. public rende invece la classe o l'organo pubblicamente accessibili, ma non ereditabile o overridable

  • private fa ora un visibile e accessibile soltanto dichiarazione racchiude, mentre fileprivate all'intero file in cui è contenuto

Maggiori dettagli here.

+0

Bello! (Mi sono preso la libertà di aggiungere la parola chiave 'var' mancante per farlo compilare.) –

+0

oh grazie mille :) Di solito copio da parco giochi e incolla, ma questa volta probabilmente ho sbagliato. – Antonio

+9

Nota a partire da gennaio 2015 questa sintassi non è corretta se la classe esterna non è 'public' - dovrebbe essere' internal' o nothing (il valore predefinito è qualunque sia la classe - 'public' o' internal') - es. 'private (set) var readonlyProperty: Int' – Grimxn

0

Come per @Antonio, è possibile utilizzare una singola proprietà per accedere come valore della proprietà readOnly pubblicamente e readWrite privatamente.Qui di seguito è la mia illustrazione:

class MyClass { 

    private(set) public var publicReadOnly: Int = 10 

    //as below, we can modify the value within same class which is private access 
    func increment() { 
     publicReadOnly += 1 
    } 

    func decrement() { 
     publicReadOnly -= 1 
    } 
} 

let object = MyClass() 
print("Initial valule: \(object.publicReadOnly)") 

//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible" 
//object.publicReadOnly += 1 

object.increment() 
print("After increment method call: \(object.publicReadOnly)") 

object.decrement() 
print("After decrement method call: \(object.publicReadOnly)") 

Ed ecco l'output:

Initial valule: 10 
    After increment method call: 11 
    After decrement method call: 10 
Problemi correlati