Swift3、4中的@objc、@objcMembers和dynamic
栏目: Objective-C · 发布时间: 7年前
内容简介: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
}
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Inside Larry's and Sergey's Brain
Richard Brandt / Portfolio / 17 Sep 2009 / USD 24.95
You’ve used their products. You’ve heard about their skyrocketing wealth and “don’t be evil” business motto. But how much do you really know about Google’s founders, Larry Page and Sergey Brin? Inside......一起来看看 《Inside Larry's and Sergey's Brain》 这本书的介绍吧!