#selector 与闭包不兼容?
The #selector is not compatible with the closure?
我尝试用闭包实现自定义函数。但 #selector
.
不支持
这是一个例子:
class Core: NSObject {
static let shared:Core = Core.init()
func button(viewController: UIViewController, button: UIButton, title: String, color: UIColor, completion: () -> Void) {
button.layer.cornerRadius = button.bounds.width / 2
button.setTitle(title, for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
button.addTarget(viewController, action: #selector(completion()), for: .touchUpInside)
}
}
Xcode 给我一个构建时间问题:
Argument of '#selector' does not refer to an '@objc' method, property, or initializer
选择器是一个字符串,用于在 Objective C 运行时识别方法、属性和初始值设定项。当您使用像 #selector(SomeClass.SomeMethod(withParam:AndParam:)
这样的符号时,您是以编译器可以轻松解析并验证其正确性的格式指定选择器。但最终,这只会被简化为 C 字符串,例如:"SomeMethodwithParam:AndParam:"
.
本质上,每个 class 都有一个字典,它将选择器映射到实现它们的代码的函数指针。当使用选择器调用函数时,Objective C 运行时会在方法 table 中搜索有问题的 class,并查找与给定选择器对应的方法实现。
这个过程无法使用闭包,闭包在定义上是匿名的。因此,您只能使用选择器来引用在 Objective C 运行时注册的方法、属性、初始化器(这就是 @objc
所做的,隐式或显式)。
您不能以这种方式调用完成块。 #selector
是项目中某处 class 中定义的函数。闭包不是有效的选择器。
将您的完成块声明为 typealias
并将完成存储为 class 的 属性。然后你会想从一个定义的函数中调用这个完成:
// Declare your completion as typealias
typealias YourCompletion = () -> Void
// At top of your class
var completion: YourCompletion?
// Then in your function declare the completion: parameter to be of type YourCompletion
func button(viewController: UIViewController, button: UIButton, title: String, color: UIColor, completion: YourCompletion) {
// Assign completion as property
self.completion = completion
// Configure your button
button.layer.cornerRadius = button.bounds.width / 2
button.setTitle(title, for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
// Have your button action be the function you'll make below
button.addTarget(viewController, action: #selector(self.callCompletion), for: .touchUpInside)
}
func callCompletion() {
if let completion = self.completion {
// Call completion
completion()
}
}
我尝试用闭包实现自定义函数。但 #selector
.
这是一个例子:
class Core: NSObject {
static let shared:Core = Core.init()
func button(viewController: UIViewController, button: UIButton, title: String, color: UIColor, completion: () -> Void) {
button.layer.cornerRadius = button.bounds.width / 2
button.setTitle(title, for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
button.addTarget(viewController, action: #selector(completion()), for: .touchUpInside)
}
}
Xcode 给我一个构建时间问题:
Argument of '#selector' does not refer to an '@objc' method, property, or initializer
选择器是一个字符串,用于在 Objective C 运行时识别方法、属性和初始值设定项。当您使用像 #selector(SomeClass.SomeMethod(withParam:AndParam:)
这样的符号时,您是以编译器可以轻松解析并验证其正确性的格式指定选择器。但最终,这只会被简化为 C 字符串,例如:"SomeMethodwithParam:AndParam:"
.
本质上,每个 class 都有一个字典,它将选择器映射到实现它们的代码的函数指针。当使用选择器调用函数时,Objective C 运行时会在方法 table 中搜索有问题的 class,并查找与给定选择器对应的方法实现。
这个过程无法使用闭包,闭包在定义上是匿名的。因此,您只能使用选择器来引用在 Objective C 运行时注册的方法、属性、初始化器(这就是 @objc
所做的,隐式或显式)。
您不能以这种方式调用完成块。 #selector
是项目中某处 class 中定义的函数。闭包不是有效的选择器。
将您的完成块声明为 typealias
并将完成存储为 class 的 属性。然后你会想从一个定义的函数中调用这个完成:
// Declare your completion as typealias
typealias YourCompletion = () -> Void
// At top of your class
var completion: YourCompletion?
// Then in your function declare the completion: parameter to be of type YourCompletion
func button(viewController: UIViewController, button: UIButton, title: String, color: UIColor, completion: YourCompletion) {
// Assign completion as property
self.completion = completion
// Configure your button
button.layer.cornerRadius = button.bounds.width / 2
button.setTitle(title, for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
// Have your button action be the function you'll make below
button.addTarget(viewController, action: #selector(self.callCompletion), for: .touchUpInside)
}
func callCompletion() {
if let completion = self.completion {
// Call completion
completion()
}
}