Domanda

Dai documenti Apple:

“Ogni modificatore a livello di accesso sopra accetta facoltativamente un singolo argomento, che consiste nel set di parole chiave racchiuso tra parentesi (ad esempio, privato (set)).Utilizzare questa forma di un modificatore a livello di accesso quando si desidera specificare un livello di accesso per il setter di una variabile o un pedice che è inferiore o uguale al livello di accesso della variabile o del pedice stesso, come discusso in gettici e setter. "

Estratto da:La società Apple."Il linguaggio di programmazione rapido." iBooks. https://itun.es/ru/jEUH0.l

Un esempio che provo a testare in Playground:

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"

Un errore che ottengo nell'output della console:

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

Che cosa sto facendo di sbagliato?Mi sto perdendo qualcosa?

PS1

Questo esempio funziona bene:

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

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

Altro dai documenti:

"Il livello di accesso per la proprietà NumberOfeDits è contrassegnato con un modificatore privato (set) per indicare che la proprietà dovrebbe essere impostabile solo all'interno dello stesso file di origine della definizione della struttura di tracciamento."

Estratto da:La società Apple."Il linguaggio di programmazione rapido." iBooks. https://itun.es/ru/jEUH0.l

enter image description here

Ma non è quello di cui ho bisogno.È possibile impedire l'impostazione della variabile numberOfEdits all'esterno della struttura/classe?

È stato utile?

Soluzione

Il tuo problema sta qui:

  set { self.name = "Unknown" }

Stai impostando il valore di una proprietà calcolata all'interno del proprio setter.Ciò causa la ricorsione infinita.Non dimenticare che questo è un calcolato proprietà:in realtà non ha spazio di archiviazione.Non hai una variabile "self.name" in cui inserire qualcosa;hai solo un paio di funzioni per calcolarlo.Le proprietà calcolate come questa dovrebbero utilizzare altre variabili non calcolate per l'archiviazione.(Ecco perché il tuo esempio di struttura funziona, comunque:stai utilizzando una proprietà immobiliare con deposito.)

Non sei aiutato nel debugging dal fatto di correre in un parco giochi.Non fraintendermi:I parchi giochi sono fantastici.Tuttavia, in questo caso, ci vogliono molti secondi per l'arresto anomalo del sistema, quindi probabilmente l'arresto anomalo non si verifica quando previsto dopo una modifica.Inoltre, non ti mostra l'analisi completa dello stack (il che è enorme per il problema che stai riscontrando, avendolo riprodotto in un'app "reale", e potrebbe aver reso piuttosto più ovvio che avresti fatto saltare lo stack.) Quando io costruito ed eseguito quanto sopra come app per console, alla fine è esploso con un'analisi dello stack profonda 104.832 chiamate, tutte tranne due delle quali erano ...private_cmd.A.name.setter....Un piccolo indizio :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top