Swift: повторный вызов замыкания, переданного через функцию идентификации, вызывает код EXC_BAD_ACCESS =2

Обновить:

Вот еще более простое воспроизведение, в котором не используются массивы (ч / т для Tim Bavaro):

func identity<T>(_ v: T) -> T {
    return v
}

var closure = {
    return
}

while true {
    closure()
    closure = identity(closure)
}

Запуск этого кода вызывает переполнение стека. Я регистрирую ошибку с помощью Swift.

Оригинал:

Оригинальное название: Swift: Массив замыканий вызывает код EXC_BAD_ACCESS =2

Я пытаюсь понять, почему этот код создает код EXC_BAD_ACCESS =2. Вот код:

var closures: [() -> ()] = []
closures.append({
    return
})

while true {
    var newClosures: [() -> ()] = []
    for closure in closures {
        closure()
        newClosures.append(closure)
    }
    closures = newClosures
}

Я пытался разобрать проблему до как можно меньшего количества строк, поэтому код может показаться немного странным и бессмысленным. (Единственный "смысл" в том, чтобы продемонстрировать мою проблему с помощью как можно меньшего количества строк).

Если вы запустите этот код в XCode как консольное приложение MacOS, вы увидите, что память распределяется без freeредактор В инструментах я вижу память выделяется при newClosures.append(closure), что имеет смысл. То, что я не понимаю, почему назначение closures в newClosures не free старая версия newClosures, Вместо этого распределение кажется бесконечным, пока я не наберу код EXC_BAD_ACCESS =2.

Стоит также отметить, что он даже не выделяет много памяти. В моем тестировании приложение вылетало после выделения около 17 МБ (оно начинается с 5 МБ и увеличивается до 17 МБ примерно за 60 с). Поэтому я думаю, что это связано с количеством сохраняемых объектов, а не с их чистым размером.

Если я заменю closures массив с массивом для некоторого другого ссылочного типа, например

class Foo { }

var foos: [Foo] = []
foos.append(Foo())

while true {
    var newFoos: [Foo] = []
    for foo in foos {
        newFoos.append(foo)
    }
    foos = newFoos
}

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

Я мог бы, вероятно, реорганизовать код, чтобы обойти эту проблему, но на данный момент я просто хочу понять, что происходит.

1 ответ

Решение

Это ошибка в Swift. Отследите проблему здесь, https://bugs.swift.org/browse/SR-7179.

Другие вопросы по тегам