Параметры типа функции быстрого именования

#swift #model-view-controller #dependency-injection

#swift #model-view-controller #внедрение зависимостей

Вопрос:

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

 class ViewController: UIViewController {
    
    private lazy var testView: TestView = {
        let view = TestView()
        view.action = action
        return view
    }()
    
    func action() {
        //stuff
    }
    
}

class TestView: UIView {
    
    var action: () -> () = {}
    
    @objc func buttonAction(_ sender: UIButton) {
        action()
    }
}
 

Приведенный выше код работает хорошо, вводя UIButton действия из View в Controller , но становится хуже, когда есть параметры, которые необходимо передать. Когда я пытаюсь изменить action внутреннюю TestView часть на,

 var action: (name: String, surname: String) -> () = { _, _ in }
 

это не позволяет мне называть String параметры. После этого я попытался изменить его как использование кортежа,

 var action: ((name: String, surname: String)) -> () = { _ in }
 

код внутри TestView работает. Однако я не могу сопоставить типы view.action = action ViewController .

Я пытаюсь сделать это по двум причинам. Один из которых заключается в том, чтобы не иметь какой-либо логической внутренней View части, а другой — легко идентифицировать и избежать путаницы с параметрами внутри ViewController по заданному имени, когда есть 2 параметра, которые будут отправлены в Controller .

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

Заранее спасибо.

Комментарии:

1. Да, мы прошли этот путь. По техническим причинам вы не можете использовать метки параметров в типе функции. Какое-то время это было возможно IIRC, но затем вселенная начала разрушаться.

2. Каким было ваше решение тогда? Если вы можете поделиться, конечно @matt

3. Вы действительно ничего не можете с этим поделать. Если вы посмотрите на собственный код Apple, он страдает от той же проблемы. Они могут объявлять тип, например developer.apple.com/documentation/uikit /… , но если вы хотите знать, что означают параметры, нет никаких меток, которые могли бы вам подсказать; вы должны прочитать документацию.

Ответ №1:

Swift не допускает именованных параметров в объявлении функции, поэтому вы можете сделать следующее:

 class TestView: UIView {
    
//    var action: () -> () = {}
    var action: (_ name: String , _ surname: String ) -> () = { _, _ in }
    
    @objc func buttonAction(_ sender: UIButton) {
        action("name", "surname")
    }
}
 

Комментарии:

1. К сожалению, это не решает проблему для Controller side.

2. Не могу сказать, что я понял, что вы имеете в виду.

3. Извините, я неправильно понял. Как только я перешел action() на Controller actioon(username: String?, password:String?) и, конечно, с вашим предложением выше, это работает. Однако проблема здесь в том, что когда некоторые читаются action("name", "surname") как строка, есть вероятность, что они не смогут определить, что есть что. (например, если нет никаких указаний, подобных namefield.text ). Я думаю, в большинстве случаев это было бы хорошо, и я могу переусердствовать.

4. Я нашел решение, и оно создает a struct с соответствующими var s в нем. И передайте его Controller .