Вопрос

от Apple Docs:

"Каждый модификатор уровня доступа выше, необязательно принимает один Аргумент, который состоит из набора ключевых слов, заключенных в скобки (например, личный (набор)). Используйте эту форму уровня доступа Модификатор, когда вы хотите указать уровень доступа для установки переменная или индекс, который меньше или равен уровню доступа сам переменная или индекс, как обсуждалось в Getter и Соседниты. "

Выдержка из: Apple Inc. «Язык программирования SWIFT». 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
.

Подробнее от документов:

"Уровень доступа для свойства NUMBOVEDITS отмечен Частный (Set) модификатор, указывающий, что имущество должно быть устроена только из того же исходного файла, что и структура трекиестринга Определение. "

Выдержка из: Apple Inc. «Язык программирования SWIFT». iBooks. https://itun.es/ru/jeuh0.l

Введите описание изображения здесь

Но это не то, что мне нужно. Можно ли запретить установить переменные Numberofedits вне структуры / класса?

Это было полезно?

Решение

Ваша проблема лежит здесь:

  set { self.name = "Unknown" }
.

Вы устанавливаете значение вычисляемого свойства внутри собственного сеттера. Это вызывает бесконечную рекурсию. Не забывайте, что это вычисляемое , вычисляется : на самом деле он на самом деле не имеет хранения. У вас нет переменной «Self.name», чтобы поставить что-либо; У вас есть только пара функций, чтобы рассчитать ее. Компьютерные свойства, такими, должны использовать другие, не вычисленные переменные для хранения. (Вот почему ваша структура пример работает, кстати: вы используете недвижимость с хранением.)

Тебе не помогают в вашей отладке по факту бега на детской площадке. Не поймите меня неправильно: игровые площадки великолепны. Однако в этом случае он принимает много секунд для сбоя, поэтому авария, вероятно, не отображается, когда вы ожидаете после редактирования. Он также не показывает вам полную трассировку стека (который массивна для проблемы, которую вы получаете, воспроизведев его в «реальном» приложении, и могло бы сделать его довольно очевидным, что вы сможете стек.) Когда я Построен и запустил вышеупомянутое в качестве приложения консоли, он наконец взорвался со стеком трассировки 104,832 вызывает глубоко, все, кроме двух из которых были генеракодицетагкод. Немного ключа :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top