Как удалить элемент из массива протоколов в Swift?
Реализация протокола Swift действительно сводит меня с ума прямо сейчас. У меня есть массив observers
, определенный по пользовательскому протоколу Observing
, и я пытаюсь удалить элемент из этого массива с учетом элемента, но Swift жалуется, что Observing
не реализует Identifiable
(который, я думаю, на самом деле другой из моих собственных протоколов, если не существует также системный протокол). Все, что я хочу сделать, это сравнение ссылок и удаление фактического объекта. Мне не нужно выполнять какие-либо сравнения с объектами.
var observers = [Observing]()
func removeObserver( observer: Observing ) {
for i in 0 ..< self.observers.count {
if self.observers[i] == observer { // <='Observing' is not convertible to 'Identifiable'...?
self.observers.removeAtIndex(i)
break
}
}
}
Ответы
Ответ 1
Оператор ==
проверяет равенство значений в Swift, а для него нет реализации по умолчанию. Вы хотите использовать ссылочное равенство, которое вы можете использовать с помощью ===
и !==
в Swift.
Подробнее см. документацию.
Операторы идентификации
Поскольку классы являются ссылочными типами, несколько констант и переменных могут ссылаться на один и тот же один экземпляр класса за кулисами. (То же самое не относится к структурам и перечислениям, поскольку они всегда копируются, когда они назначаются константе или переменной или передаются функции.)
Иногда бывает полезно узнать, относятся ли две константы или переменные к одному и тому же экземпляру класса. Чтобы включить это, Swift предоставляет два идентификационных оператора:
Идентично (===) Не идентично (! ==)
Обратите внимание, что для работы оператора ===
объекты должны соответствовать протоколу AnyObject
. Вы можете гарантировать это путем суффикса протокола с помощью ": class", например:
protocol SomeProtocol : class { ... }
Ответ 2
Если вы хотите сравнить, если две точки наблюдения относятся к одному экземпляру, используйте вместо этого оператор ===. Это требует, чтобы наблюдатель должен соответствовать AnyObject. Простым способом требовать, чтобы Observing применялся только к AnyObjects, было бы добавить префикс @class_protocol к объявлению протокола.