Вычисляемый установщик для индекса массива в Swift

Короче говоря, я хочу достичь, например:

var actions: [String]{
    get{
        if (_actions==nil){
            _actions = []
        }
        return _actions!
    }
    set{
        _actions = newValue
    }
    subscript(index:Int) -> String{
      set {
         assert(index<_actions.count && index>=0, "Index out of range")
         _actions[index] = newValue
      }
    }
}

Я знаю, что подстрочный индекс не является средством доступа к массиву, но какая же самая удобная альтернатива для этого?

Я действительно ценю за краткие ответы, если это возможно! Большое спасибо!

Редактировать:

Чтобы расширить мое объяснение @jrturton,

То, чего я пытаюсь добиться, - это когда бы действие [i] было установлено на newValue, я хотел бы сделать несколько дополнительных вычислений, таких как изменение положения подвида действий [i].

Но если я скажу actions[3] = "randomMethod", вычисляется установщик для всего массива. Правильно? Поэтому я хотел бы найти способ, чтобы, когда actions[3] установлен в newValue, функция repositionView(3) можно позвонить, например.

Я знаю другие способы сделать это, но мой вопрос просто спрашивает, есть ли более удобный способ, такой как приведенный выше пример: компьютерный сеттер, чтобы делать то, что я хочу?

Изменить 2:

Чтобы показать @Vatsal Manot, что я действительно имею в виду, я удалил getter для subscript, и вот полный пример.swift(который не запускается из-за ошибки):

import UIKit
import Foundation

class DWActionsSubmenu: UIView{
    var actions: [DWAction]{
        get{
            if (_actions==nil){
                _actions = []
            }
            return _actions!
        }
        set{
            _actions = newValue
        }
        subscript(index:Int) -> DWAction{
            set {
                assert(index<_actions.count && index>=0, "Index out of range")
                _actions[index] = newValue
                a()
            }
        }
    }

    var _actions: [DWAction]?

    init(actions:[DWAction]?){
        super.init()
        _actions = actions
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
    }

    func a(){

    }
}

2 ответа

Решение

Я бы обернул ваш список действий в пользовательский класс, к которому вы можете получить доступ через подписку. Затем вы можете добавить блок для запуска всякий раз, когда задан подписанный член:

class ActionList {
    private var actions = [String]()

    var actionDidChange : ((Int) -> ())?

    subscript(actionIndex:Int) -> String {
        get {
            return actions[actionIndex]
        }
        set {
            actions[actionIndex] = newValue
            if let actionDidChange = actionDidChange {
                actionDidChange(actionIndex)
            }
        }
    }

    func addAction(action: String) {
        actions.append(action)
    }

    func addActions(newActions:[String]) {
        actions += newActions
    }
}

Использование (на детской площадке):

let actionList = ActionList()
actionList.actionDidChange = {
    actionIndex in
    println("Action \(actionIndex) did change")
}

actionList.addActions(["One", "Two", "Three"])
actionList[2] = "New"
// Prints "Action 2 did change"

Следующее должно работать:

var actions: [String] = []

subscript(index:Int) -> String
{
    get
    {
        assert(index < actions.count && index >= 0, "Index out of range")
        return actions[index]
    }

    set(newValue)
    {
        assert(index < actions.count && index >= 0, "Index out of range")
        actions[index] = newValue
    }
}
Другие вопросы по тегам