Кажется, что в синтаксисе списка захвата Swift наблюдается любопытный синтаксический сбой. Если я объявляю несколько захваченных переменных, захват спецификатор относится только к первому:Почему спецификатор захвата необязателен в списках захвата?
let closure = { [unowned x, y] in … }
Теперь я хотел бы ожидать y
быть unowned
, но это, кажется, не так:
class Test {
var callback: (Void -> Void)?
init() {
print("init")
}
deinit {
print("deinit")
}
}
func makeScope() {
let x = Test()
let y = Test()
y.callback = { [unowned x, y] in
print(y)
}
}
makeScope()
print("done")
Это печатает:
init
init
deinit
done
Так y
, кажется, сильно захвачен и создает сохранить цикл, предотвращая объект от того, сделка располагается. Это так? Если да, имеет ли смысл разрешить «пустой» спецификатор захвата в списке? Или есть причина, почему [unowned x, y]
не рассматривается как [unowned x, unowned y]
?
Хороший улов, спасибо. Считаете ли вы, что компилятор имеет смысл хотя бы выдать предупреждение, если спецификатор отсутствует перед ссылочным типом? – zoul
@zoul: Нет, см. Пример выше. –
Отлично, спасибо! Я думаю, что то, что делает меня несчастным, состоит в том, что простой, обычный случай «unowned x, y» выглядит ошибочным (ср.'int a, b' в C-подобных языках), в то время как редкий случай привязки ссылочного типа без указателя может быть легко (и более явно!) решен с использованием временной переменной. – zoul