Ваша собственность (неявно) объявлена readwrite
в ObjC.Это означает, что вы можете изменить свойство, записав новый экземпляр NSArray
, который заменяет старый (в этом случае константы нового экземпляра можно получить, сначала прочитав другой экземпляр NSArray
, который является существующим значением свойства):
NSArray *currentObjects = self.customObjects;
// one of many ways to derive one immutable array from another:
NSArray *newArray = [currentObjects subarrayWithRange:NSMakeRange(1, currentObjects.count - 1)];
self.customObjects = newArray;
В Swift ваше свойство выглядит как Swift.Array
(то есть тип Array
из стандартной библиотеки Swift), который является типом значения.Каждое назначение семантически создает копию.(Дорогая работа по выполнению копирования может быть отложена с использованием шаблона «копировать при записи». Массивы ссылочных типов, таких как объекты, копируют ссылки вместо хранилища, поэтому по сути это «мелкая копия».)
Операции Mutating также делают это:
let currentObjects1 = self.customObjects
currentObjects1.remove(0) // compile error
// currentObjects1 is a `let` constant so you can't mutate it
var currentObjects = self.customObjects
currentObjects.remove(0) // ok
print(self.customObjects.count - currentObjects.count)
// this is 1, because currentObjects is a copy of customObjects
// we mutated the former but not the latter so their count is different
self.customObjects = currentObjects
// now we've replaced the original with the mutated copy just as in the ObjC example
Когда у вас есть свойство readwrite в Swift, и тип этого свойства имеет тип значения, такой как Array
(или тип ObjC, который связан сТип значения, например NSArray
), вы можете использовать методы мутации непосредственно в свойстве.Это потому, что вызов метода мутации семантически эквивалентен чтению (и копированию) существующего значения, изменению копии и последующей записи измененной копии.
// all equivalent
self.customObjects.remove(0)
self.customObjects = self.customObjects.dropFirst(1)
var objects = self.customObjects; objects.remove(0); self.customObjects = objects
Кстати: если вы разрабатываетеAPI для рассматриваемого класса ObjC здесь, вы можете подумать о том, чтобы сделать ваше свойство customObjects
ненулевым - если нет значимой семантической разницы между пустым массивом и отсутствующим массивом, ваши клиенты Swift сочтут это трудоемким, чтобы различать два.