Swift 4: неноминальный тип «T» не поддерживает явную инициализацию при преобразовании Objective-c в Swift.

Я пытаюсь преобразовать проект Objective-C в Swift, вот один из файлов .h в Objective-C:

typedef void(^PrintBlock)(HLPrinter *printer);

@interface ShoppingViewController : UIViewController

@property (copy, nonatomic) PrintBlock printBlock;

@end

а в .m файле есть функция:

HLPrinter *printer = [self getPrinter];

if (_printBlock) {
    _printBlock(printer);
}

И вот как я преобразовал его в Swift:

typealias PrintBlock = (_ printer: HLPrinter?) -> Void

Но когда я попытался преобразовать функцию выше в Swift, я получаю ошибку 'Non-nominal type 'PrintBlock' (aka '(Optional<HLPrinter>) -> ()') does not support explicit initialization', когда пытаюсь объявить переменную с типом PrintBlock:

let pb = PrintBlock()

Я не знаком с Objective-C, так как мне преобразовать эту функцию с _printerBlock в Swift?


person SensEyeNULL    schedule 29.05.2018    source источник
comment
Вы инициализируете PrintBlock с помощью PrintBlock(), что не разрешено делать   -  person Prashant Tukadiya    schedule 29.05.2018


Ответы (2)


PrintBlock — это псевдоним замыкания. Вы не можете просто создать экземпляр, как класс или структуру. Вам нужно назначить замыкание (или функцию) свойству.

Код Swift будет таким:

typealias PrintBlock = (_ printer: HLPrinter?) -> Void

class ShoppingViewController: UIViewController {
    var printBlock: PrintBlock?

    func getPrinter() -> HLPrinter {
        return somePrinter
    }

    func someFunction() {
        if let printBlock = printBlock {
            let printer = getPrinter()
            printBlock(printer)
        }
    }
}

Код вызова будет примерно таким:

let vc = ShoppingViewController()
vc.printBlock = { (printer) in
    // do something with printer
}

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

func someFunction(_ printer: HLPrinter) {
}

Вы можете назначить это:

vc.printBlock = someFunction

Здесь есть несколько предположений, основанных на частичной информации, которую вы предоставили в своем вопросе.

person rmaddy    schedule 29.05.2018

Вы не можете инициализировать Closure. Для вашего требования вы можете просто создать переменную, как свойство в objc

typealias Listener = (HLPrinter) -> ()

var lister:Listener?

И на каком-то событии

 self.lister?(value) 

Надеюсь, это полезно

person Prashant Tukadiya    schedule 29.05.2018