Я предполагаю, что цель этого вопроса состояла в том, чтобы иметь возможность опубликовать ответ, показывающий, как autoreleasepool
на самом деле является универсальным методом, возвращающим любое значение, возвращаемое его закрытием. Было предложено, что можно сделать:
for i in 0...10 {
if (
!autoreleasepool {
// do stuff
// return false for break, true for continue.
return true
}
) {
break
}
}
Хотя это откровенно, когда мы впервые обнаруживаем, что многие из этих методов синхронного замыкания на самом деле являются обобщениями, которые возвращают то, что делает замыкание, я не думаю, что это является особенно хорошим примером его применения. Если вам нужны комментарии в вашем коде, чтобы объяснить, что означает возвращаемое значение, это запах кода для более глубокой проблемы. Я думаю, что подход Рмадди (+1) гораздо яснее, гораздо проще рассуждать. Есть хорошие варианты использования autoreleasepool
, возвращающие тот же Result
, что и у замыкания, но это не так, ИМХО.
Давайте рассмотрим более убедительное использование autoreleasepool
возвращаемых типов. Давайте представим, что у вас есть какая-то рутина, которая делает следующее (я убрал вызовы GCD, чтобы держать наше внимание на autoreleasepool
):
func generateAllImages() {
for index in 0 ..< imageCount {
let image = generateImage(for: index)
updateUserInterface(for: index, with: image)
}
}
И давайте скажем, что во время профилирования приложения мы обнаружили, что внутри generateImage
было спрятано что-то, что создало объект автоматического выпуска, что сделало пиковое использование памяти нашим приложением действительно резким. Понятно, что вы могли бы сделать следующее, чтобы уменьшить верхнюю отметку приложения, опустошая пул автоматического выпуска на каждой итерации:
func generateAllImages() {
for index in 0 ..< imageCount {
autoreleasepool {
let image = generateImage(for: index)
updateUserInterface(for: index, with: image)
}
}
}
Но если вы подтвердили, что ваш объект автоматического выпуска был ограничен рамками generateImage
, вы можете немного привести в порядок это:
func generateAllImages() {
for index in 0 ..< imageCount {
let image = autoreleasepool { generateImage(for: index) }
updateUserInterface(for: index, with: image)
}
}
Это не только более кратко, но и проясняет, где был создан объект автоматического выпуска. Этот шаблон кажется мне очень естественным и убедительным использованием autoreleasepool
поведения возврата объекта, возвращаемого его замыканием.