Как изменить свойство элемента NSObject в массиве Swift, а затем добавить его в тот же массив - PullRequest
0 голосов
/ 01 декабря 2018

У меня есть класс NSObject следующим образом:

class Number: NSObject {
    var number: Int = 0

    init(newNumber: Int) {
        self.number = newNumber
    }
}

И затем я создаю массив этого Number объекта следующим образом:

var numbersArr = [Number(newNumber: 1), Number(newNumber: 2)]

Теперь я хочуизменить number свойство элемента существующего массива и добавить его в качестве нового элемента.Я делаю это так:

var newItem = numbersArr[1]
newItem.number = 4
numbersArr(newItem)

Я ожидаю, что новое значение numbersArr будет [1, 2, 4], но я получаю [1, 4, 4].

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

Я не могу инициализировать новый Number объект и затем добавить его.В моем текущем классе NSObject есть и другие свойства, которые должны оставаться такими же.

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Ваша проблема является распространенной при работе с ссылочным типом.Вы с индексами 1 и 2 из numbersArr указывают на один и тот же объект, поэтому, когда вы изменяете один, вы также изменяете и другой.

Вам необходимо сделать глубокую копию :

class Number: NSObject, NSCopying {
    var number: Int = 0

    init(newNumber: Int) {
        self.number = newNumber
    }

    func copy(with zone: NSZone? = nil) -> Any {
        return Number(newNumber: self.number)
    }
}

var numbersArr = [Number(newNumber: 1), Number(newNumber: 2)]
let newItem = numbersArr[1].copy() as! Number
newItem.number = 4
numbersArr.append(newItem)
0 голосов
/ 01 декабря 2018

Почти так же, как и решение Джона Монтгомери, но небольшое обновление.

func copy () -> Number {

    let number = Number(newNumber: self.number)

    //Copy your all other NSObject properties here
    //Example
    number.example = self.example

    return number
}

Теперь попробуйте,

let newItem = numbersArr[1].copy() // Here it copies your number with all NSObject properties.
newItem.number = 4
numbersArr.append(newItem) // [1, 2, 4]
0 голосов
/ 01 декабря 2018

Это невозможно.Природа ссылочных типов заключается в том, что изменение значения для одной ссылки изменяет его для всех них.Ваши единственные варианты:

  1. Вместо этого используйте структуру
  2. Инициализируйте новый объект

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

class Number: NSObject {
    var number: Int = 0

    init(newNumber: Int) {
        self.number = newNumber
    }

    func copy () -> Number {
        return Number(newNumber: self.number)
    }
}

И затем:

let newItem = numbersArr[1].copy()
newItem.number = 4
numbersArr.append(newItem) // [1, 2, 4]
...