Swift3、4中的@objc、@objcMembers和dynamic
栏目: Objective-C · 发布时间: 6年前
内容简介:Objective-C 对象是基于运行时的,方法或属性使用动态派发 ,在运行调用时再决定实际调用的具体实现。而 Swift 为了追求性能,如果没有特殊需要的话,是不会在运行时再来决定这些的。也就是说,Swift 类型的成员或者方法在编译时就已经决定,而运行时便不再需要经过一次查找,而可以直接使用。Objective-C 中所有类都继承自Swift4 后继承自
Objective-C 对象是基于运行时的,方法或属性使用动态派发 ,在运行调用时再决定实际调用的具体实现。而 Swift 为了追求性能,如果没有特殊需要的话,是不会在运行时再来决定这些的。也就是说,Swift 类型的成员或者方法在编译时就已经决定,而运行时便不再需要经过一次查找,而可以直接使用。
Objective-C 中所有类都继承自 NSObject
,Swift 中的类如果要供 Objective-C 调用,必须也继承自 NSObject
。
@objc
-
@objc修饰符的根本目的是用来暴露接口给 Objective-C 的运行时(类、协议、属性和方法等) -
添加
@objc修饰符并不意味着这个方法或者属性会采用 Objective-C 的方式变成动态派发,Swift 依然可能会将其优化为静态调用 -
@objc修饰符的隐式添加:-
Swift 3 中继承自
NSObject的类,不需要手动添加@objc,编译器会给所有的非private的类和成员加上@objc,private接口想要暴露给 Objective-C 需要@objc的修饰button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) @objc private func backButtonTapped() { } func backButtonTapped() { } 复制代码 -
Swift 4 中继承自
NSObject的类的隐式@objc自动添加,只会发生在以下四种情况:- 重写了父类的 Objective-C 方法
- 实现了一个 Objective-C 的协议
-
@IBAction或@IBOutlet关键字的修饰 -
@NSManaged关键字的修饰
-
-
使用
@objc可以修改 Swift 接口暴露到 Objective-C 后的名字@objc(Squirrel) class Белка: NSObject { @objc(color) var цвет: Цвет = .Красный @objc(hideNuts:inTree:) func прячьОрехи(количество: Int, вДереве дерево: Дерево) { } } 复制代码
@objcMembers
Swift4 后继承自 NSObject
的类不再隐式添加 @objc
关键字,但在某些情况下非常依赖 Objective-C 的运行时(如 XCTest),所以在 Swift4 中提供了 @objcMembers
关键字,对类和子类、扩展和子类扩展重新启用 @objc
推断。
@objcMembers
class MyClass : NSObject {
func foo() { } // implicitly @objc
func bar() -> (Int, Int) // not @objc, because tuple returns
// aren't representable in Objective-C
}
extension MyClass {
func baz() { } // implicitly @objc
}
class MySubClass : MyClass {
func wibble() { } // implicitly @objc
}
extension MySubClass {
func wobble() { } // implicitly @objc
}
复制代码
使用 @objc
和 @nonobjc
可以指定开启或关闭某一 extension
中的所有方法的 @objc
推断。
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
}
复制代码
dynamic
当前 Swift 的动态性依赖于 Objective-C,Swift3 中 dynamic
就隐式包含了 @objc
的意思,但考虑到以后版本的 Swift 语言和运行时将会自支持 dynamic
而不再依赖于 Objective-C,所以在 Swift4 中将 dynamic
和 @objc
含义进行了抽离。
class MyClass {
dynamic func foo() { } // error: 'dynamic' method must be '@objc'
@objc dynamic func bar() { } // okay
}
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Code Complete
Steve McConnell / Microsoft Press / 2004-6-19 / GBP 40.99
在线阅读本书 Widely considered one of the best practical guides to programming, Steve McConnells original CODE COMPLETE has been helping developers write better software for more than a decade. Now......一起来看看 《Code Complete》 这本书的介绍吧!