Обновление объекта SwiftyJSON, созданного из запроса Alamofire

Я пытаюсь отобразить некоторые данные JSON, полученные с веб-сайта, в виде таблицы. Изначально все работает отлично. Я объявляю свои данные JSON как переменную экземпляра:

var tableData:JSON!
{
    didSet
    {
        tableView.reloadData()
    }
}

И затем я делаю свой запрос где-то - viewDidLoad или viewWillAppear, или через пользователя, вытягивающего tableView для обновления или что-то еще, на самом деле не имеет значения - устанавливаю данные, и таблица перезагружается. Все отлично работает.

request(method, url, parameters: parameters, encoding: ParameterEncoding.URL).responseJSON(options: NSJSONReadingOptions.AllowFragments) { (request, response, json, error) -> Void in
            self.tableData = JSON(json!)
        }

Однако иногда я хочу не просто отображать данные, а позволить пользователю обновлять данные, например, в текстовом поле. И вот тут я сталкиваюсь с проблемами.

Итак, я создал ячейку табличного представления с текстовым полем, заполнил ее текстом, извлеченным из моего tableData JSON, пока все хорошо. Затем мой пользователь может изменить текстовое поле, и я хочу обновить tableData с помощью методов делегата текстового поля. Это не работает для меня.

func textFieldDidEndEditing(textField: UITextField)
{
    let key = "anExampleKey"
    tableData[key] = JSON(textField.text)
    println(tableData[key]) // the original value, not textField.text
}

Кажется, ничего не происходит, значение tableData для "anExampleKey" остается неизменным. Итак, если эта ячейка прокручивается, например, за пределы экрана, а затем возвращается в поле зрения, любые изменения, внесенные моим пользователем, теряются, и она возвращается к исходному значению.

Однако это проблема исключительно со значением JSON, созданным из запроса Alamofire. Например, если я сделаю это:

func textFieldDidEndEditing(textField: UITextField)
{
    let key = "anExampleKey"
    var json = JSON([key:tableData[key].stringValue])
    tableData[key] = JSON(textField.text)
    json[key] = JSON(textField.text)
    println(tableData[key]) // the original value, not textField.text
    println(json[key]) // textField.text
}

Переменная json будет обновлена, чтобы отразить текстовое поле, в то время как tableData по-прежнему будет иметь исходное значение, а не то, что находится в текстовом поле. Кто-нибудь знает, почему объект JSON, созданный с помощью запроса Alamofire, является неизменным, а объект, созданный непосредственно из словаря, - нет?


person Devin    schedule 28.07.2015    source источник


Ответы (1)


Хорошо, я понял это. Это не имеет никакого отношения к SwiftyJSON или Alamofire, а скорее к тому факту, что я объявил свою переменную экземпляра как необязательную развернутую. Я все еще не совсем уверен во всех правилах для необязательных и неявно развернутых переменных, но использую обычную переменную JSON вместо JSON! разрешил обновить.

var tableData:JSON! /* won't update */
var tableData:JSON = JSON([:]) /* will update */ 

Я понятия не имею, почему это так. Я думал, что уже разобрался с необязательными и неявно развернутыми правилами Swift, но, похоже, это не так. Это почти как каждый раз, когда я неявно разворачиваю JSON! переменная, он создает новую копию и обновляет ее, оставляя переменную экземпляра неизменной. Я запустил игровую площадку, чтобы увидеть, верно ли это для всех неявно развернутых структур, и это не так, я могу просто обновить значения экземпляра для неявно развернутой структуры. Интересно, необязательный JSON? значения обновляются.

struct Test
{
    var myVar = 0
}

var myTest:Test!

myTest = Test() /* myVar = 0 */
myTest.myVar = 7 /* myVar = 7 */
myTest.myVar /* myVar = 7 still */

var implicitlyUnwrappedJSON:JSON!
implicitlyUnwrappedJSON = JSON(["Test":"This is one"])
implicitlyUnwrappedJSON["Test"] = "This is another one"
implicitlyUnwrappedJSON["Test"].string /* This is one */
implicitlyUnwrappedJSON?["Test"] = "This is another one"
implicitlyUnwrappedJSON["Test"].string /* This is another one */
implicitlyUnwrappedJSON!["Test"] = "This is another one yet"
implicitlyUnwrappedJSON["Test"].string /* This is another one yet */

var optionalJSON:JSON?
optionalJSON = JSON(["Test":"This is one"])
optionalJSON?["Test"] = "This is another one"
optionalJSON?["Test"].string /* This is another one */
optionalJSON!["Test"] = "This is another one yet"
optionalJSON!["Test"].string /* This is another one yet */

var json:JSON = JSON(["Test":"This is one"])
json["Test"] = "This is another one"
json["Test"].string /* This is another one */

Так что я понятия не имею, что здесь происходит, но у меня это работает.

person Devin    schedule 29.07.2015