web-dev-qa-db-fra.com

Swift en lecture seule externe, propriété interne en lecture-écriture

Dans Swift, quelle est la méthode classique pour définir le modèle courant dans lequel une propriété doit être lue de manière externe, mais modifiable en interne par la classe (et les sous-classes) qui la possède.

En Objective-C, les options suivantes sont disponibles:

  • Déclarez la propriété en lecture seule dans l'interface et utilisez une extension de classe pour accéder à la propriété en interne. Ceci est un accès basé sur les messages, donc il fonctionne bien avec KVO, atomicity, etc.
  • Déclarez la propriété en lecture seule dans l'interface, mais accédez à l'ivar de sauvegarde en interne. Comme l'accès par défaut pour un ivar est protégé, cela fonctionne bien dans une hiérarchie de classes, où les sous-classes pourront également modifier la valeur, mais le champ est en lecture seule.

Dans Java), la convention est la suivante:

  • Déclarez un champ protégé et implémentez un getter public en lecture seule.

Quel est l'idiome pour Swift?

96
Jasper Blues

Pour une propriété de classe, vous pouvez spécifier un niveau d'accès différent en préfixant la déclaration de propriété avec le modificateur d'accès suivi de get ou set entre parenthèses. Par exemple, une propriété de classe avec un getter public et un setter privé sera déclarée comme:

private(set) public var readonlyProperty: Int

Lecture suggérée: Getters and Setters

Les considérations de Martin concernant le niveau d'accessibilité sont toujours valables - c.-à-d. Qu'il n'y a pas de modificateur protected, internal ne restreint l'accès qu'au module, private au fichier actuel uniquement et public sans restrictions.

Swift 3 notes

2 nouveaux modificateurs d'accès, fileprivate et open ont été ajoutés à la langue, tandis que private et public ont été légèrement modifiés:

  • open s'applique uniquement aux classes et aux membres de la classe: il permet de sous-classer une classe ou de remplacer un membre en dehors du module où ils sont définis. public rend la classe ou le membre accessible au public, mais ne peut pas être hérité ni remplacé

  • private rend maintenant un membre visible et accessible à partir de la déclaration uniquement, alors que fileprivate au fichier entier dans lequel il est contenu

Plus de détails ici .

206
Antonio

Selon @Antonio, nous pouvons utiliser une seule propriété pour accéder publiquement à la valeur de la propriété readOnly et à readWrite à titre privé. Ci-dessous mon illustration:

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)")

Et voici la sortie:

  Initial  valule: 10
  After increment method call: 11
  After decrement method call: 10
1
Santosh