2016-07-20 4 views
1

Я пытаюсь использовать метод set для вызова функции после изменения значения.Набор свойств протокола Swift не выполнен

Я не понял, почему метод set не вызывается.

Код может быть непосредственно выполнен в детской площадке

//: Playground - noun: a place where people can play 

import UIKit 

protocol RandomItem { 
    var range : (Int,Int) {get set} 
    var result : Int {get set} 

    init() 
    mutating func createRandom() 
} 

extension RandomItem { 
    var range : (Int,Int) { 
     get { 
      return range 
     } 
     set { 
      range = newValue 
      self.createRandom() 
     } 
    } 
} 

struct Item: RandomItem { 
    var range = (0,1) 
    var result: Int = 0 

    init() { 
     self.createRandom() 
    } 

    mutating func createRandom() { 
     let low = UInt32(range.0) 
     let high = UInt32(range.1) 
     result = Int(arc4random_uniform(high - low + 1) + low) 
    } 
} 
+1

Аксессоры расширения выполняют бесконечный рекурсивный вызов. Это кажется фиктивным. –

ответ

0

Ваш STRUCT Item заявляет о своей собственной range собственности, который переопределяет созданный в расширении протокола по умолчанию. Объект range в Item не имеет определителей или определителей, чтобы сделать то, что делает ваша версия расширения.

Еще одна проблемы:

Вашего расширение протокола определяет свойство range как вычисленная собственность (без хранения), чей газопоглотитель и инкубационном как называют себя. Это будет бесконечно.

Может быть, вы ищете что-то более, как:

protocol RandomItem { 
    var storedRange: (Int, Int) { get } 
    var range : (Int,Int) {get set} 
    var result : Int {get set} 

    init() 
    mutating func createRandom() 
} 

extension RandomItem { 
    var range : (Int,Int) { 
     get { 
      return storedRange 
     } 
     set { 
      storedRange = newValue 
      self.createRandom() 
     } 
    } 
} 

struct Item: RandomItem { 
    var result: Int = 0 
    var storedRange = (0, 1) 

    init() { 
     self.createRandom() 
    } 

    mutating func createRandom() { 
     let low = UInt32(range.0) 
     let high = UInt32(range.1) 
     result = Int(arc4random_uniform(high - low + 1) + low) 
    } 
} 

Это требует типа конформного для определения сохраненного свойства storedRange, что реализация по умолчанию вычисленных собственностей range будет взаимодействовать с.

+0

Элемент имеет (автогенерированные) аксессоры, которые переопределяют функции, унаследованные от протокола. –

+0

Мне пришлось расширять переменную storedRange с помощью параметра set, но затем я работаю так, как ожидалось. благодаря – madcat