Swift массивы используют значение (копия) семантику, но на самом деле они передаются и назначаются в качестве ссылок. Только когда происходит изменение размера массива или переупорядочения элементов, массив действительно копируется. Это называется «ленивая копия» или «копирование при записи». Вы не должны бояться, чтобы просто присвоить массив так:
var temp = someBigArray
Это не скопирована. Но когда вы позвоните:
temp.append(someValue)
Тогда происходит фактическая копия.
В коде в этой строке:
if var table = self.database[tableName]
Массив не скопирована.
В этой строке:
table.append(theRecord)
Это является скопирована.
В этой строке:
self.database[tableName] = table
Это не скопирована, но арбитр подсчета массива в словаре уменьшается на единицу и, если нет других ссылок на этот массив не существует, то он освобождается. Затем массив «table» просто передается как ссылка в «self.database [tableName]». Здесь нет копии.
Но ответ Эрика D верен, вызвав append() непосредственно на массив (с помощью оператора?) Создается наименьшая служебная информация. Это, как вы должны это сделать:
self.database[tableName]?.append(theRecord)
Но это может произойти также в Append(), что массив получить скопировали - что в случае, если размер массива должен быть расширен и нет заранее выделенного пространства , Это связано с тем, что массивы всегда должны иметь непрерывную память.
Так, позвонив Append() может случиться так, что массив должен сделать это:
- выделить новый блок памяти смежный с текущим размером счета плюс, по крайней мере, один вход больше. (обычно он выделяет даже больше, чем это, на всякий случай, когда вы добавите больше в будущем)
- скопируйте все содержимое в новый блок памяти (включая новую запись)
- освободите «старую» память (это на самом деле сложнее, потому что другие массивы могут ссылаться на старую память, в этом случае она не отпущена)
Как правило, вам не нужно заботиться о «неэффективной» копии массивов - компилятор знает лучше.
Благодарим вас за это элегантное решение. Таким образом, это ни на какой стадии не скопирует (большую) таблицу базы данных? Мне жаль, что я еще не могу продвинуться. – John
Добро пожаловать. Действительно, в этой версии нет копии. 1-я часть проверяет нуль, вторая часть создает массив с одним элементом, 3-я часть добавляет к массиву только в том случае, если он существует (и мы проверили, что он делает это, и это не сработает). – Moritz
Я думаю, что это не совсем так, потому что есть хотя бы один экземпляр, который мы должны сделать для сравнения с 'nil'. Мы используем getter, и это скопирует массив один раз. Поправьте меня если я ошибаюсь. (Btw. Копии не так уж плохи в Swift. Копии также легкие и быстрые ... Я также облегчил бы ваш код, как этот 'if self.database [tableName] ?. append (theRecord) == nil {self. database [tableName] = [theRecord]} '. Это не имеет никакого значения для функциональности, но лучше читать по-моему. – DevAndArtist