Во втором чтении, кажется, вижу:
Вам нужно return
сразу после completion(.success(with: taskLists[index]))
, в противном случае вы все равно будете выполнять оставшуюся часть функции, которая включает в себя рекурсивный вызов.
В общем, я бы посоветовал изменить вашу функцию следующим образом:
public func completeResolveTaskList(listName: INSpeakableString, with completion: @escaping (INTaskListResolutionResult) -> Void) {
print("completeResolveTaskList")
let allLists = getAllLists()
guard let matching = allLists.first(where: { $0.spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() }) else {
switch allLists.count {
case 0:
completion(.unsupported())
default:
completion(.disambiguation(with: taskLists))
}
return
}
completion(.success(with: matching))
}
Это соответствует, мне кажется, потоку немного ближе и более быстрым способом. Конечно, оператор else для оператора guard
немного длиннее, но вы всегда можете изменить его в другом методе. В общем, это больше похоже на «достань мне первый элемент, который соответствует входным данным. Если ты не найдешь ни одного, сделай какой-нибудь запасной вариант, в противном случае действуй как обычно». Это также избавляет от перебора списка с индексом.