문제

Apple Docs :

"위의 각 액세스 수준 수정자는 선택적으로 하나씩 수용됩니다. 괄호로 묶인 키워드 세트로 구성된 인수 (예를 들어, 개인 (세트)). 이 형식의 액세스 수준을 사용하십시오 수정 자의 설정터의 액세스 수준을 지정하려는 경우 액세스 수준보다 작거나 같은 변수 또는 첨자 getter에서 설명한 것처럼 변수 또는 첨자 자체 및 setters. "

발췌문 : Apple Inc. "Swift Programming Language." iBooks. https://itun.es/ru/jeuh0.l

놀이터에서 테스트하려고하는 예제 :

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

콘솔 출력에 들어가는 오류 :

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
.

나는 무엇을 잘못하고 있습니까? 나는 뭔가를 놓치고 있니?

PS1

이 예제는 잘 작동합니다.

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

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

Docs의 다른 것 :

"numberOfedits 속성의 액세스 수준은 개인 (세트) 수정자가 속성을 설정할 수 있음을 나타냅니다. TrackedString 구조의 동일한 소스 파일 내에서만 정의. "

발췌문 : Apple Inc. "Swift Programming Language." iBooks. https://itun.es/ru/jeuh0.l

여기에 이미지 설명

그러나 그것이 필요한 것이 아닙니다. struct / class 외부의 변수 numberOfedits를 설정할 수 없습니까?

도움이 되었습니까?

해결책

문제가 있습니다 :

  set { self.name = "Unknown" }
.

자체 세터 내에 계산 된 속성 값을 설정합니다. 이로 인해 무한 재귀가 발생합니다. 이것이 계산 된 속성임을 잊지 마십시오. 실제로 저장소가 없습니다. 어떤 것도 넣을 변수 "self.name"가 없습니다. 당신은 그것을 계산할 수있는 몇 가지 기능 만 가지고 있습니다. 이와 같은 계산 된 속성은 저장을 위해 다른 비 계산 변수를 사용해야합니다. (즉, 구조 예제가 작동하는 이유는 다음과 같습니다. 스토리지가있는 실제 속성을 사용하고 있습니다.)

놀이터에서 실행하기 때문에 디버깅에 도움이되지 않습니다. 나에게 틀리지 마라. 놀이터가 멋지다. 그러나이 경우 충돌하는 데 몇 초가 걸리므로 편집 후에 기대할 때 충돌이 발생하지 않을 것입니다. 그것은 또한 당신에게 완전한 스택 추적 (당신이 얻는 문제를 위해 거대한 것, "진짜"앱에서 그것을 복제하고, 스택을 날아 갔다는 것을 알게되었을 수 있습니다.) 위의 콘솔 응용 프로그램으로 지어졌고, 마침내 스택 추적 104,832로 전화를 걸어 두 개가 모두 ...private_cmd.A.name.setter...였습니다. 단서의 비트 :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top