Question

Apple docs:

“Chaque niveau d'accès modificateur ci-dessus accepte éventuellement un seul l'argument, qui se compose de l'ensemble de mots entre parenthèses (par exemple, privé(set)).Utilisez ce formulaire de un niveau d'accès modificateur si vous voulez spécifier un niveau d'accès pour le setter d'une variable ou indice qui est inférieur ou égal au niveau d'accès de la variable ou de l'indice lui-même, tel que discuté dans les Accesseurs et Les Setters.”

Extrait De:Apple Inc.“La Swift Langage de Programmation.” iBooks. https://itun.es/ru/jEUH0.l

Un exemple que j'ai essayer de tester en terrain de jeu:

import UIKit


class A {
  private(set) var name: String {
  get { return "Hello, \(self.name)" }
  set { self.name = "Unknown" }
  }

  init(_ name:String) {
    self.name = name
  }
}

let a = A("Andrew")
a.name = "Hello"

Une erreur que j'obtiens dans la Console de Sortie:

Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0x7fff5056eff8).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0xea721, 0x00000001104f308c libsystem_pthread.dylib`__mtx_droplock + 222, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7fff5056eff8)
  * frame #0: 0x00000001104f308c libsystem_pthread.dylib`__mtx_droplock + 222
    frame #1: 0x00000001104f2f07 libsystem_pthread.dylib`pthread_mutex_unlock + 68
    frame #2: 0x000000010ffbd2b5 libc++.1.dylib`std::__1::mutex::unlock() + 9
    frame #3: 0x000000010f040b94 libswift_stdlib_core.dylib`swift_getGenericMetadata + 260
    frame #4: 0x000000010ef28a24 libswift_stdlib_core.dylib`Swift.IndexingGenerator.init <A : Swift._Collection>(Swift.IndexingGenerator<A>.Type)(A) -> Swift.IndexingGenerator<A> + 164
    frame #5: 0x000000010ef55f1a libswift_stdlib_core.dylib`protocol witness for Swift._Sequence_.generate <A : Swift._Sequence_>(@inout Swift._Sequence_.Self)() -> Swift._Sequence_.Self.GeneratorType in conformance Swift._ContiguousArrayBuffer : Swift._Sequence_ + 154
    frame #6: 0x000000010ef284d5 libswift_stdlib_core.dylib`Swift._copyCollectionToNativeArrayBuffer <A : protocol<Swift._Collection, Swift._Sequence_>>(A) -> Swift._ContiguousArrayBuffer<A.GeneratorType.Element> + 1061
    frame #7: 0x000000010ef40281 libswift_stdlib_core.dylib`Swift.Array.convertFromArrayLiteral <A>(Swift.Array<A>.Type)(Swift.Array<A>...) -> Swift.Array<A> + 641
    frame #8: 0x000000010f1eaae4 PlaygroundLogger`Swift.UInt64.toBytes (Swift.UInt64)() -> Swift.Array<Swift.UInt8> + 292
    frame #9: 0x000000010f1eb6a4 PlaygroundLogger`protocol witness for PlaygroundLogger.ToBytes.toBytes <A : PlaygroundLogger.ToBytes>(@inout PlaygroundLogger.ToBytes.Self)() -> Swift.Array<Swift.UInt8> in conformance Swift.UInt64 : PlaygroundLogger.ToBytes + 20
    frame #10: 0x000000010f1dbe3d PlaygroundLogger`PlaygroundLogger.BytesStream.write (PlaygroundLogger.BytesStream)(PlaygroundLogger.ToBytes) -> PlaygroundLogger.BytesStream + 77
    frame #11: 0x000000010f1dbd74 PlaygroundLogger`PlaygroundLogger.BytesStream.write (PlaygroundLogger.BytesStream)(Swift.String) -> PlaygroundLogger.BytesStream + 164
    frame #12: 0x000000010f20f04b PlaygroundLogger`PlaygroundLogger.PlaygroundWriter.encode_config_info (PlaygroundLogger.PlaygroundWriter)() -> () + 203
    frame #13: 0x000000010f20f2bf PlaygroundLogger`PlaygroundLogger.PlaygroundWriter.encode_header (PlaygroundLogger.PlaygroundWriter)() -> () + 127
    frame #14: 0x000000010f20ecda PlaygroundLogger`PlaygroundLogger.PlaygroundScopeWriter.encode_scope_event (PlaygroundLogger.PlaygroundScopeWriter)(PlaygroundLogger.ScopeEvent) -> () + 58
    frame #15: 0x000000010f1eb997 PlaygroundLogger`playground_log_scope_entry + 87
    frame #16: 0x000000011ae20771

Ce que je fais mal?Ai-je raté quelque chose?

PS1

Cet exemple fonctionne très bien:

struct TrackedString {
  private(set) var numberOfEdits = 0
  var value: String = "" {
  didSet {
    numberOfEdits++
  }
  }
}

var stringToEdit = TrackedString()
stringToEdit.value = "Hello"
stringToEdit
stringToEdit.numberOfEdits += 10
stringToEdit

Plus de docs:

“le niveau d'accès à la numberOfEdits propriété est marquée avec un privé(set) modificateur pour indiquer que la propriété doit être réglable seulement à partir du même fichier source comme le TrackedString de la structure définition”.

Extrait De:Apple Inc.“La Swift Langage de Programmation.” iBooks. https://itun.es/ru/jEUH0.l

enter image description here

Mais ce n'est pas ce dont j'ai besoin.Est-il possible d'interdire de définir la variable numberOfEdits à l'extérieur de la structure/classe?

Était-ce utile?

La solution

Votre problème se trouve ici:

  set { self.name = "Unknown" }

Vous êtes à la définition de la valeur d'une propriété calculée à l'intérieur de son propre incubateur.Cela provoque une récursion infinie.N'oubliez pas que c'est un calculé propriété:il ne fait pas de stockage.Vous n'avez pas de variable "self.le nom de" mettre quelque chose dans;vous avez seulement un couple de fonctions pour le calculer.Les propriétés calculées comme cela devrait utiliser d'autres, non les variables calculées pour le stockage.(C'est pourquoi votre structure exemple des œuvres, par la voie:vous utilisez un bien immobilier, avec le stockage.)

Vous n'êtes pas aidé dans votre débogage en fait de la course dans une aire de Jeux.Ne vous méprenez pas:Les terrains de jeux sont grands.Toutefois, dans ce cas, c'est prendre plusieurs secondes à se bloquer, de sorte que le crash n'est probablement pas visible lorsque vous attendre à la suite d'une modification.Il n'est également pas montrant une trace de la pile (ce qui est énorme pour le problème que vous obtenez, après avoir reproduit, dans une "vraie" application, et aurait peut-être fait-il plutôt plus évident que l'on venait d'exploser la pile.) Quand j'ai construit et a couru le ci-dessus comme une application console, enfin, elle s'est affirmée avec une trace de la pile 104,832 appels de profondeur, tous, sauf deux, qui ont été ...private_cmd.A.name.setter....Bit de signe :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top