zoukankan      html  css  js  c++  java
  • swift 与 @objc

     Objective-C entry points

    https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md

    Before Swift 4, the compiler made some Swift declarations automatically available to Objective-C. For example, if one subclassed from NSObject, the compiler created Objective-C entry points for all methods in such classes. The mechanism is called @objc inference.

    In Swift 4, such automatic @objc inference is deprecated because it is costly to generate all those Objective-C entry points. When "Swift 3 @objc Inference" setting is set to "On", it allows the old code to work. However, it will show deprecation warnings that need to be addressed. It is recommended to "fix" these warnings and switch the setting to "Default", which is the default for new Swift projects.

    https://stackoverflow.com/questions/44379348/the-use-of-swift-3-objc-inference-in-swift-4-mode-is-deprecated

    The whole reason for this warning in the first place is the result of SE-0160. Prior to Swift 4, internal or higher Objective-C compatible members of NSObject inheriting classes were inferred to be @objc and therefore exposed to Objective-C, therefore allowing them to be called using selectors (as the Obj-C runtime is required in order to lookup the method implementation for a given selector).

    However in Swift 4, this is no longer the case. Only very specific declarations are now inferred to be @objc, for example, overrides of @objc methods, implementations of @objc protocol requirements and declarations with attributes that imply @objc, such as @IBOutlet.

    The motivation behind this, as detailed in the above linked proposal, is firstly to prevent method overloads in NSObject inheriting classes from colliding with each other due to having identical selectors. Secondly, it helps reduce the binary size by not having to generate thunks for members that don't need to be exposed to Obj-C, and thirdly improves the speed of dynamic linking.

    If you want to expose a member to Obj-C, you need to mark it as @objc, for example:

    class ViewController: UIViewController {

        @IBOutlet weak var button: UIButton!

        override func viewDidLoad() {

            super.viewDidLoad()

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

        }

        @objc func foo() {

           // ... 

        }

    }

    (the migrator should do this automatically for you with selectors when running with the "minimise inference" option selected)

    To expose a group of members to Obj-C, you can use an @objc extension:

    @objc extension ViewController {

        // both exposed to Obj-C

        func foo() {}

        func bar() {}

    }

    This will expose all the members defined in it to Obj-C, and give an error on any members that cannot be exposed to Obj-C (unless explicitly marked as @nonobjc).

    If you have a class where you need all Obj-C compatible members to be exposed to Obj-C, you can mark the class as @objcMembers:

    @objcMembers

    class ViewController: UIViewController {

       // ...

    }

    Now, all members that can be inferred to be @objc will be. However, I wouldn't advise doing this unless you really need all members exposed to Obj-C, given the above mentioned downsides of having members unnecessarily exposed.

    https://stackoverflow.com/questions/44390378/how-can-i-deal-with-objc-inference-deprecation-with-selector-in-swift-4#

  • 相关阅读:
    OpenCV:Python3使用OpenCV
    CNN结构:MXNet设计和实现简介
    环的寻找:寻找无向图中所有存在的环-删除点法
    JAVA 构建使用 Native 库
    Android:JAVA使用HDF5存储
    Java:数值-字符串转换(String转Double)
    Qt无法用UTF-8编辑问题
    Boost-QT兼容问题:#define FUSION_HASH #
    JAVA;使用java.awt.Image的不稳定性
    图方法:寻找无向图联通子集的JAVA版本
  • 原文地址:https://www.cnblogs.com/feng9exe/p/9675743.html
Copyright © 2011-2022 走看看