Каковы последствия никогда не вызывать обработчик завершения функции? - PullRequest
0 голосов
/ 26 января 2019

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

func completeMe(completionHandler: @escaping (String?) -> Void) {
   return
}

Ответы [ 2 ]

0 голосов
/ 26 января 2019

По сути, в «обработчике завершения» нет ничего особенного.Это просто функция.

Если у вас есть функция:

func f() {
    print("Hello, world")
}

, и вы не вызываете ее, что происходит потом?Ну, ничего не происходит.

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

Представьте, что функция вызывается контроллером представления, который запускает действиеиндикатор, прежде чем он вызывает, а затем в завершении он останавливает индикатор.Если завершение никогда не вызывается, то индикатор никогда не прекращает вращаться.

По сути, все. Если завершение не вызывается, его код не запускается .Эффекты этого полностью зависят от того, что происходит в коде внутри и вокруг завершения.


Хорошо, вы упомянули память ... В большинстве случаев обработчик завершения будет анонимнымфункция.В этом случае - это созданный объект.Но он подчиняется тем же правилам управления памятью, что и любой другой объект.Нет утечки только потому, что она не называется.Если completeMe выглядит так:

func completeMe(_ completionHandler: (String) -> Void) {
    completionHandler("Hello, world")
}

и вы называете это так:

completeMe({ self.detailLabel.text = $0 })

Тогда объект, созданный для анонимной функции, не доживет до того момента, когда completeMeвозвращается.Если вы сохраняете анонимную функцию:

func completeMe(_ completionHandler: @escaping (String) -> Void) {
    self.handler = completionHandler
    // Do other things
}

Затем происходит то же самое, что и с любым другим объектом: анонимная функция действует до тех пор, пока этому свойству не будет присвоено другое значение (учитывая также, что ничто иное не имеет ссылки на него) .

И если вы передаете именованную функцию в,

func takeAString(_ s: String) {
    print(s)
}

completeMe(takeAString)

время жизни takeAStringуже время жизни программы;здесь нет никаких последствий для управления памятью.

Если вы передадите метод экземпляра, управление памятью будет таким же, как если бы вы передали сам экземпляр.


* Обычно при сбоевозможно, вы либо а) будете иметь второе завершение "сбоя", либо б) завершение будет сигнализировать об ошибке через свой аргумент.

0 голосов
/ 26 января 2019

Поскольку параметр назван completionHandler, вызывающая сторона будет предполагать, что он будет выполнен, несмотря ни на что.

Итак, чтобы ответить на ваш вопрос, никаких побочных эффектов не будет, но это можно считать плохой практикой.

...