swift的@objc总结

One can explicitly write @objc on any Swift declaration that can be expressed in Objective-C.

 @objc相关的参量只能修饰类、类的成员、扩展以及只能被类实现的协议;

下面开列修饰的情况和说明

 

一、无修饰

NSObject-derived classes no longer infer @objc

 

A declaration within an NSObject-derived class will no longer infer @objc. For example:

class MyClass : NSObject {

  func foo() { } // not exposed to Objective-C in Swift 4

}

 

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.

 

https://www.cnblogs.com/feng9exe/p/9675743.html

 

二、@objc修饰

1、修饰类:不再使用;

2、修饰扩展:扩展中的成员全部暴露给oc;

3、修饰协议:实现全部暴露;

4、修饰成员:暴露给oc;

 

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

@objc extension ViewController{….}

 

说明:

1、NSObject-derived classes no longer infer @objc

2Other cases currently supported (e.g., a method declared in a subclass of NSObject) would no longer infer @objc, but one could continue to write it explicitly to produce Objective-C entry points.

3、扩展中的缺省实现无法继承,修饰为@objc后会被编译器进一步修饰为@objc and dynamic从而实现可继承性;

 

三、@objcMembers

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:

 

四、@nonobjc进行反向操作

 

五、原理与代价

The final observation is that there is a cost for each Objective-C entry point, because the Swift compiler must create a "thunk" method that maps from the Objective-C calling convention to the Swift calling convention and is recorded within Objective-C metadata. This increases the size of the binary (preliminary tests on some Cocoa[Touch] apps found that 6-8% of binary size was in these thunks alone, some of which are undoubtedly unused), and can have some impact on load time (the dynamic linker has to sort through the Objective-C metadata for these thunks).

 

 

六、使用代码示例

 

@objc protocol MyDelegate {

    func bar()

}

 

class MyClass : MyDelegate {

    /* inferred @objc */

    func bar() { }

}

 

class SwiftClass { }

 

@objc extension SwiftClass {

  func foo() { }            // implicitly @objc

  func bar() -> (Int, Int)  // error: tuple type (Int, Int) not

      // expressible in @objc. add @nonobjc or move this method to fix the issue

}

 

@objcMembers

class MyClass : NSObject {

  func wibble() { }    // implicitly @objc

}

 

@nonobjc extension MyClass {

  func wobble() { }    // not @objc, despite @objcMembers

}

 

 

参考资料:

https://www.cnblogs.com/feng9exe/p/9675743.html

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

 

posted @ 2019-03-26 19:33  zzfx  阅读(1605)  评论(0编辑  收藏  举报