热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在Swift4中使用#selector()处理@objc推理弃用?

如何解决《如何在Swift4中使用#selector()处理@objc推理弃用?》经验,为你挑选了3个好方法。

我正在尝试将我的项目源代码从Swift 3转换为Swift 4.一个警告Xcode给我的是我的选择器.

例如,我使用常规选择器将按钮添加到按钮,如下所示:

button.addTarget(self, action: #selector(self.myAction), for: .touchUpInside)

这是它显示的警告:

'#selector'的参数是指'ViewController'中的实例方法'myAction()',它取决于Swift 4中不推荐使用的'@objc'属性推断

添加'@objc'以将此实例方法公开给Objective-C

现在,点击Fix错误消息对我的函数执行此操作:

// before
func myAction() { /* ... */ }

// after
@objc func myAction() { /* ... */ }

我真的不想重命名我的所有函数来包含@objc标记,我假设没有必要.

如何重写选择器来处理弃用?


相关问题:

不推荐在Swift 4模式下使用Swift 3 @objc推理?

Hamish.. 152

修复 - 它是正确的 - 您可以更改选择器,以使其引用的方法暴露给Objective-C.

这个警告的全部原因首先是SE-0160的结果.在Swift 4 internal或更高版本之前,NSObject继承类的Objective-C兼容成员被推断为@objc并因此暴露给Objective-C,因此允许使用选择器调用它们(因为需要Obj-C运行时才能查找方法给定选择器的实现).

但是在Swift 4中,情况已经不再如此.现在只推断出非常具体的声明@objc,例如,@objc方法的覆盖,@objc协议要求的实现和具有暗示的属性的声明@objc,例如@IBOutlet.

如上述链接提议中所详述的,其背后的动机首先是防止NSObject继承类中的方法重载由于具有相同的选择器而彼此冲突.其次,它有助于减少二进制大小,因为不必为不需要暴露给Obj-C的成员生成thunk,第三,提高了动态链接的速度.

如果要将成员公开给Obj-C,则需要将其标记为@objc,例如:

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        button.addTarget(self, action: #selector(foo), for: .touchUpInside)
    }

    @objc func foo() {
       // ... 
    }
}

(当选择"最小化推理"选项运行时,迁移器应该使用选择器自动执行此操作)

要将一组成员公开给Obj-C,您可以使用@objc extension:

@objc extension ViewController {

    // both exposed to Obj-C
    func foo() {}
    func bar() {}
}

这会将其中定义的所有成员公开给Obj-C,并对任何无法向Obj-C公开的成员发出错误(除非明确标记为@nonobjc).

如果您有一个类,您需要将所有 Obj-C兼容成员暴露给Obj-C,您可以将该类标记为@objcMembers:

@objcMembers
class ViewController: UIViewController {
   // ...
}

现在,所有可以推断出来的成员都@objc将是.但是,我不建议这样做,除非你真的需要暴露给Obj-C的所有成员,因为上面提到了让成员不必要地暴露的缺点.



1> Hamish..:

修复 - 它是正确的 - 您可以更改选择器,以使其引用的方法暴露给Objective-C.

这个警告的全部原因首先是SE-0160的结果.在Swift 4 internal或更高版本之前,NSObject继承类的Objective-C兼容成员被推断为@objc并因此暴露给Objective-C,因此允许使用选择器调用它们(因为需要Obj-C运行时才能查找方法给定选择器的实现).

但是在Swift 4中,情况已经不再如此.现在只推断出非常具体的声明@objc,例如,@objc方法的覆盖,@objc协议要求的实现和具有暗示的属性的声明@objc,例如@IBOutlet.

如上述链接提议中所详述的,其背后的动机首先是防止NSObject继承类中的方法重载由于具有相同的选择器而彼此冲突.其次,它有助于减少二进制大小,因为不必为不需要暴露给Obj-C的成员生成thunk,第三,提高了动态链接的速度.

如果要将成员公开给Obj-C,则需要将其标记为@objc,例如:

class ViewController: UIViewController {

    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        button.addTarget(self, action: #selector(foo), for: .touchUpInside)
    }

    @objc func foo() {
       // ... 
    }
}

(当选择"最小化推理"选项运行时,迁移器应该使用选择器自动执行此操作)

要将一组成员公开给Obj-C,您可以使用@objc extension:

@objc extension ViewController {

    // both exposed to Obj-C
    func foo() {}
    func bar() {}
}

这会将其中定义的所有成员公开给Obj-C,并对任何无法向Obj-C公开的成员发出错误(除非明确标记为@nonobjc).

如果您有一个类,您需要将所有 Obj-C兼容成员暴露给Obj-C,您可以将该类标记为@objcMembers:

@objcMembers
class ViewController: UIViewController {
   // ...
}

现在,所有可以推断出来的成员都@objc将是.但是,我不建议这样做,除非你真的需要暴露给Obj-C的所有成员,因为上面提到了让成员不必要地暴露的缺点.


男人选择器是一团糟.似乎所有其他快速更新他们都在搞乱它.为什么我们不能只为方法拥有一个纯粹的swift自动完成选择器.使代码看起来如此丑陋.
@Sti所以直接回答"*是否没有纯粹的Swift方式向按钮添加目标?或者使用选择器?*" - 不,没有"纯粹的Swift"方式使用选择器来调度方法.它们依赖于Obj-C运行时以查找方法实现以调用特定的选择器--Swift运行时没有该功能.
我不明白这一点.我没有Objective-C代码.没有纯粹的Swift方式向按钮添加目标吗?或者使用选择器?我不希望我的代码充满这个属性.是因为UIButton来自某些NSObject/Obj-c-thing?
为什么Xcode在将代码转换为最新语法时不会自动执行此操作?

2> Kiran Sarvai..:

作为Apple官方文档.你需要使用@objc来调用你的选择器方法.

在Objective-C中,选择器是一种引用Objective-C方法名称的类型.在Swift中,Objective-C选择器由Selector结构表示,并且可以使用#selector 表达式构造.要为可以从Objective-C调用的方法创建选择器,请传递方法的名称,例如 #selector(MyViewController.tappedButton(sender:)).要为属性的Objective-C getter或setter方法构造选择器,请传递以getter:or setter:标签为前缀的属性名称,例如 #selector(getter: MyViewController.myButton).



3> 小智..:

至于我认为Swift 4.2,您需要做的就是将@IBAction分配给您的方法,您可以避免这种愚蠢的@objc注释

```

let tap  =  UITapGestureRecognizer(target: self, action: #selector(self.cancel))


@IBAction func cancel()
{
    self.dismiss(animated: true, completion: nil)
}


推荐阅读
author-avatar
PHP先锋官
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有