adi*_*dib 11 objective-c swift
我想知道Swift在调用方法时id是什么,在方法中可以在运行时确定方法的可用性.具体来说,我想在Swift中做这个模式:
-(IBAction) handleEvent:(id) sender {
BOOL didDisable = NO;
if([sender respondsToSelector:@selector(setEnabled:)]) {
[sender setEnabled:NO];
didDisable = YES;
}
[self doSomethingAsyncWithCompletionHandler:^{
if(didDisable) {
[sender setEnabled:YES];
}
}];
}
Run Code Online (Sandbox Code Playgroud)
最大的问题是 setEnabled:在Swift中作为属性导入(例如UIBarItem)并且以下构造都没有编译
func handleEvent(sender: AnyObject) {
// Error: AnyObject does not have a member named "enabled"
sender.enabled? = false
// Error: (BooleanLiteralCompatible) -> _ is not identical to Bool
sender.setEnabled?(false)
}
Run Code Online (Sandbox Code Playgroud)
mat*_*att 24
事实上,你可以按照以前的方式完成它:通过调用respondsToSelector:.实际上,这正是您提出的表达式所做的:
sender.setEnabled?(false)
Run Code Online (Sandbox Code Playgroud)
该表达式实际上是一个简写 - 它respondsToSelector:首先调用,然后setEnabled:仅在respondsToSelector:测试通过时调用.不幸的是,正如你所说,你无法编译代码.然而,这仅仅是斯威夫特已知的可用方法库的一个怪癖.事实是,虽然编译它有点棘手,但它可以完成 - 一旦你得到它编译,它的行为就像你期望的那样.
但是,我不打算解释如何编译它,因为我不想鼓励这种诡计.在Swift中不鼓励这种动态消息传递.一般而言,Swift中不需要动态消息传递技巧,例如键值编码,内省等,并且与Swift的强类型方法不一致.以Swift的方式做事情会更好,通过选择性地投射到你有理由相信这个东西可能具有enabled属性的东西.例如:
@IBAction func doButton(sender: AnyObject) {
switch sender {
case let c as UIControl: c.enabled = false
case let b as UIBarItem: b.enabled = false
default:break
}
}
Run Code Online (Sandbox Code Playgroud)
要么:
@IBAction func doButton(sender: AnyObject) {
(sender as? UIControl)?.enabled = false
(sender as? UIBarItem)?.enabled = false
}
Run Code Online (Sandbox Code Playgroud)
在Swift 2.0 beta 4中,您的祈祷得到了回应; 这段代码变得合法:
@IBAction
func handleEvent(sender: AnyObject) {
if sender.respondsToSelector("setHidden:") {
sender.performSelector("setHidden:", withObject: true)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2023 次 |
| 最近记录: |