Swift报错:非命名类型'PrintBlock'不支持显式初始化——OC转Swift求助
正确转换Objective-C Block到Swift的方法
首先,咱们先理清你遇到的问题:你错误地尝试直接初始化一个函数类型的变量,而函数类型(也就是你定义的PrintBlock)不能像类/结构体那样用()来初始化,得给它赋值一个符合该类型的闭包才行。下面一步步给你讲正确的转换方式:
1. 正确定义类型别名(Typealias)
你的Objective-C代码里,PrintBlock是接受一个HLPrinter *参数、无返回值的block。对应到Swift,如果你确定getPrinter()返回的打印机对象不会是nil,可以这样定义:
typealias PrintBlock = (HLPrinter) -> Void
如果OC里的getPrinter()有可能返回nil,那把参数改成可选类型:
typealias PrintBlock = (HLPrinter?) -> Void
2. 定义ViewController的属性
OC里的@property (copy, nonatomic) PrintBlock printBlock;对应到Swift,应该声明为可选类型的闭包属性(因为OC里的block属性默认是nullable的,允许为nil):
class ShoppingViewController: UIViewController { // Swift里闭包赋值时会自动处理copy,不需要手动指定 var printBlock: PrintBlock? }
3. 正确调用闭包(对应OC里的_printBlock(printer))
OC里先判断block是否存在再调用的逻辑,在Swift里有两种等价写法:
写法一:可选绑定(更清晰)
let printer = getPrinter() // 假设这是你的获取打印机的方法 // 先判断printBlock是否存在,再调用 if let executePrint = printBlock { executePrint(printer) }
写法二:可选链调用(更简洁)
Swift里支持直接用可选链调用闭包,当printBlock为nil时,调用会自动被忽略:
let printer = getPrinter() printBlock?(printer)
为什么你之前的let pb = PrintBlock()会报错?
PrintBlock是一个函数类型,不是可以实例化的类或者结构体。如果你想创建一个PrintBlock类型的变量,需要给它赋值一个符合该类型的闭包,比如:
// 创建一个符合PrintBlock类型的闭包 let pb: PrintBlock = { printer in // 这里写你要执行的打印逻辑,比如: print("打印设备:\(printer)") } // 然后可以把这个闭包赋值给ViewController的属性 let vc = ShoppingViewController() vc.printBlock = pb
内容的提问来源于stack exchange,提问作者Compound07
相关产品推荐
相关产品推荐

