如何在 objc.io 中国 中 使用 swift

页面导航:
→ 正文内容 Swift调用Objective-C API
Swift调用Objective-C编写的API实例
这篇文章主要介绍了Swift调用Objective-C编写的API实例,介绍的比较全面和详细,对Objective-C代码的重复利用有极大好处,的朋友可以参考下
互用性是让 Swift 和 Objective-C 相接合的一种特性,使你能够在一种语言编写的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,你应该懂得如何利用互用性来重新定义并提高你写 Cocoa 应用的方案。
互用性很重要的一点就是允许你在写 Swift 代码时使用 Objective-C 的 API 接口。当你导入一个 Objective-C 框架后,你可以使用原生的 Swift 语法实例化它的 Class 并且与之交互。
为了使用 Swift 实例化 Objective-C 的 Class,你应该使用 Swift 语法调用它的一个初始化器。当 Objective-C 的init方法变化到 Swift,他们用 Swift 初始化语法呈现。“init”前缀被截断当作一个关键字,用来表明该方法是初始化方法。那些以“initWith”开头的init方法,“With”也会被去除。从“init”或者“initWith”中分离出来的这部分方法名首字母变成小写,并且被当做是第一个参数的参数名。其余的每一部分方法名依次变味参数名。这些方法名都在圆括号中被调用。
举个例子,你在使用 Objective-C 时会这样做:
//Objective-C
UITableView *myTableView = [[UITableView alloc]
initWithFrame:CGRectZero style:UITableViewStyleGrouped];
在 Swift 中,你应该这样做:
let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)
你不需要调用 alloc,Swift 能替你处理。注意,当使用 Swift 风格的初始化函数的时候,“init”不会出现。
你可以在初始化时显式的声明对象的类型,也可以忽略它,Swift 能够正确判断对象的类型。
let myTextField = UITextField(frame: CGRect(0.0, 0.0, 200.0, 40.0))
这里的UITableView和UITextField对象和你在 Objective-C 中使用的具有相同的功能。你可以用一样的方式使用他们,包括访问属性或者调用各自的类中的方法。
为了统一和简易,Objective-C 的工厂方法也在 Swift 中映射为方便的初始化方法。这种映射能够让他们使用同样简洁明了的初始化方法。例如,在 Objective-C 中你可能会像下面这样调用一个工厂方法:
//Objective-C
UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];
在 Swift 中,你应该这样做:
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)
在 Swift 中访问和设置 Objective-C 对象的属性时,使用点语法:
myTextField.textColor = UIColor.darkGrayColor()
myTextField.text = "Hello world"
if myTextField.editing {
&&& myTextField.editing = false
当 get 或 set 属性时,直接使用属性名称,不需要附加圆括号。注意,darkGrayColor后面附加了一对圆括号,这是因为darkGrayColor是UIColor的一个类方法,不是一个属性。
在 Objective-C 中,一个有返回值的无参数方法可以被作为一个隐式的访问函数,并且可以与访问器使用同样的方法调用。但在 Swift 中不再能够这样做了,只有使用@property关键字声明的属性才会被作为属性引入。
在 Swift 中调用 Objective-C 方法时,使用点语法。
当 Objective-C 方法转换到 Swift 时,Objective-C 的selector的第一部分将会成为方法名并出现在圆括号的前面,而第一个参数将直接在括号中出现,并且没有参数名,而剩下的参数名与参数则一一对应的填入圆括号中。
举个例子,你在使用 Objective-C 时会这样做:
//Objective-C
[myTableView insertSubview:mySubview atIndex:2];
在 Swift 中,你应该这样做:
myTableView.insertSubview(mySubview, atIndex: 2)
如果你调用一个无参方法,仍必须在方法名后面加上一对圆括号
myTableView.layoutIfNeeded()
id 兼容性(id Compatibility)
Swift 包含一个叫做AnyObject的协议类型,表示任意类型的对象,就像 Objective-C 中的id一样。AnyObject协议允许你编写类型安全的 Swift 代码同时维持无类型对象的灵活性。因为AnyObject协议保证了这种安全,Swift 将 id 对象导入为 AnyObject。
举个例子,跟 id 一样,你可以为AnyObject类型的对象分配任何其他类型的对象,你也同样可以为它重新分配其他类型的对象。
var myObject: AnyObject = UITableViewCell()
myObject = NSDate()
你也可以在调用 Objective-C 方法或者访问属性时不将它转换为具体类的类型。这包括了 Objcive-C 中标记为 @objc 的方法。
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
然而,由于直到运行时才知道AnyObject的对象类型,所以有可能在不经意间写出不安全代码。另外,与 Objective-C 不同的是,如果你调用方法或者访问的属性 AnyObject 对象没有声明,将会报运行时错误。比如下面的代码在运行时将会报出一个 unrecognized selector error 错误:
myObject.characterAtIndex(5)
// crash, myObject does't respond to that method
但是,你可以通过 Swift 的 optinals 特性来排除这个 Objective-C 中常见的错误,当你用AnyObject对象调用一个 Objective-C 方法时,这次调用将会变成一次隐式展开 optional(implicitly unwrapped optional)的行为。你可以通过 optional 特性来决定 AnyObject 类型的对象是否调用该方法,同样的,你可以把这种特性应用在属性上。
举个例子,在下面的代码中,第一和第二行代码将不会被执行因为length属性和characterAtIndex:方法不存在于 NSDate 对象中。myLength常量会被推测成可选的Int类型并且被赋值为nil。同样你可以使用if-let声明来有条件的展开这个方法的返回值,从而判断对象是否能执行这个方法。就像第三行做的一样。
let myLength = myObject.length?
let myChar = myObject.characterAtIndex?(5)
if let fifthCharacter = myObject.characterAtIndex(5) {
&&& println("Found \(fifthCharacter) at index 5")
对于 Swift 中的强制类型转换,从 AnyObject 类型的对象转换成明确的类型并不会保证成功,所以它会返回一个可选的值。而你需通过检查该值的类型来确认转换是否成功。
let userDefaults = NSUserDefaults.standardUserDefaults()
let lastRefreshDate: AnyObject? = userDefaults.objectForKey("LastRefreshDate")
if let date = lastRefreshDate as? NSDate {
&&& println("\(date.timeIntervalSinceReferenceDate)")
当然,如果你能确定这个对象的类型(并且确定不是nil),你可以添加as操作符强制调用。
let myDate = lastRefreshDate as NSDate
let timeInterval = myDate.timeIntervalSinceReferenceDate
在Objective-C中,对象的引用可以是值为NULL的原始指针(同样也是Objective-C中的nil)。而在Swift中,所有的值C包括结构体与对象的引用C都被保证为非空。作为替代,你将这个可以为空的值包装为optional type。当你需要宣告值为空时,你需要使用nil。你可以在中了解更多。
因为Objective-C不会保证一个对象的值是否非空,Swift在引入Objective-C的API的时候,确保了所有函数的返回类型与参数类型都是optional,在你使用Objective-C的API之前,你应该检查并保证该值非空。 在某些情况下,你可能绝对确认某些Objective-C方法或者属性永远不应该返回一个nil的对象引用。为了让对象在这种情况下更加易用,Swift使用 implicitly unwrapped optionals 方法引入对象, implicitly unwrapped optionals 包含optional 类型的所有安全特性。此外,你可以直接访问对象的值而无需检查nil。当你访问这种类型的变量时, implicitly unwrapped optional 首先检查这个对象的值是否不存在,如果不存在,将会抛出运行时错误。
扩展(Extensions)
Swift 的扩展和 Objective-C 的类别(Category)相似。扩展为原有的类,结构和枚举丰富了功能,包括在 Objective-C 中定义过的。你可以为系统的框架或者你自己的类型增加扩展,只需要导入合适的模块并且保证你在 Objective-C 中使用的类、结构或枚举拥有相同的名字。
举个例子,你可以扩展UIBezierPath类来为它增加一个等边三角形,这个方法只需提供三角形的边长与起点。
extension UIBezierPath {
&&& convenience init(triangleSideLength: Float, origin: CGPoint) {
&&&&&&& self.init()
&&&&&&& let squareRoot = Float(sqrt(3))
&&&&&&& let altitude = (squareRoot * triangleSideLength) / 2
&&&&&&& moveToPoint(origin)
&&&&&&& addLineToPoint(CGPoint(triangleSideLength, origin.x))
&&&&&&& addLineToPoint(CGPoint(triangleSideLength / 2, altitude))
&&&&&&& closePath()
你也可以使用扩展来增加属性(包括类的属性与静态属性)。然而,这些属性必须是通过计算才能获取的,扩展不会为类,结构体,枚举存储属性。下面这个例子为CGRect类增加了一个叫area的属性。
extension CGRect {
&&& var area: CGFloat {
&&& return width * height
let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
let area = rect.area
// area: CGFloat = 500.0
你同样可以使用扩展来为类添加协议而无需增加它的子类。如果这个协议是在 Swift 中被定义的,你可以添加 comformance 到它的结构或枚举中无论它们在 Objective-C 或在 Swift 中被定义。
你不能使用扩展来覆盖 Objective-C 类型中存在的方法与属性。
闭包(Closures)
Objective-C 中的blocks会被自动导入为 Swift 中的闭包。例如,下面是一个 Objective-C 中的 block 变量:
//Objective-C
void (^completionBlock)(NSData *, NSError *) = ^(NSData *data, NSError *error) {/* ... */}
而它在 Swift 中的形式为
let completionBlock: (NSData, NSError) -& Void = {data, error in /* ... */}
Swift 的闭包与 Objective-C 中的 blocks 能够和睦相处,所以你可以把一个 Swift 闭包传递给一个把 block 作为参数的 Objective-C 函数。Swift 闭包与函数具有互通的类型,所以你甚至可以传递 Swift 函数的名字。
闭包与 blocks 语义上想通但是在一个地方不同:变量是可以直接改变的,而不是像 block 那样会拷贝变量。换句话说,Swift 中变量的默认行为与 Objective-C 中 __block 变量一致。
当比较两个 Swift 中的对象时,可以使用两种方式。第一种,使用(==),判断两个对象内容是否相同。第二种,使用(===),判断常量或者变量是否为同一个对象的实例。
Swift 与 Objective-C 一般使用 == 与 === 操作符来做比较。Swift 的 == 操作符为源自 NSObject 的对象提供了默认的实现。在实现 == 操作符时,Swift 调用 NSObject 定义的 isEqual: 方法。
NSObject 类仅仅做了身份的比较,所以你需要在你自己的类中重新实现 isEqual: 方法。因为你可以直接传递 Swift 对象给 Objective-C 的 API,你也应该为这些对象实现自定义的 isEqual: 方法,如果你希望比较两个对象的内容是否相同而不是仅仅比较他们是不是由相同的对象派生。
作为实现比较函数的一部分,确保根据实现对象的hash属性。更进一步的说,如果你希望你的类能够作为字典中的键,也需要遵从Hashable协议以及实现hashValues属性。
Swift 类型兼容性
当你定义了一个继承自NSObject或者其他 Objective-C 类的 Swift 类,这些类都能与 Objective-C 无缝连接。所有的步骤都有 Swift 编译器自动完成,如果你从未在 Objective-C 代码中导入 Swift 类,你也不需要担心类型适配问题。另外一种情况,如果你的 Swift 类并不来源自 Objectve-C 类而且你希望能在 Objecive-C 的代码中使用它,你可以使用下面描述的 @objc 属性。
@objc可以让你的 Swift API 在 Objective-C 中使用。换句话说,你可以通过在任何 Swift 方法、类、属性前添加@objc,来使得他们可以在 Objective-C 代码中使用。如果你的类继承自 Objective-C,编译器会自动帮助你完成这一步。编译器还会在所有的变量、方法、属性前加 @objc,如果这个类自己前面加上了@objc关键字。当你使用@IBOutlet,@IBAction,或者是@NSManaged属性时,@objc也会自动加在前面。这个关键字也可以用在 Objetive-C 中的 target-action 设计模式中,例如,NSTimer或者UIButton。
当你在 Objective-C 中使用 Swift API,编译器基本对语句做直接的翻译。例如,Swift API func playSong(name: String)会被解释为- (void)playSong:(NSString *)name。然而,有一个例外:当在 Objective-C 中使用 Swift 的初始化函数,编译器会在方法前添加“initWith”并且将原初始化函数的第一个参数首字母大写。例如,这个 Swift 初始化函数init (songName: String, artist: String将被翻译为- (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist 。
Swift 同时也提供了一个@objc关键字的变体,通过它你可以自定义在 Objectiv-C 中转换的函数名。例如,如果你的 Swift 类的名字包含 Objecytive-C 中不支持的字符,你就可以为 Objective-C 提供一个可供替代的名字。如果你给 Swift 函数提供一个 Objecytive-C 名字,要记得为带参数的函数添加(:)
@objc(Squirrel)
class Белка {
&&& @objc(initWithName:)
&&& init (имя: String) { /*...*/ }
&&& @objc(hideNuts:inTree:)
&&& func прячьОрехи(Int, вДереве: Дерево) { /*...*/ }
当你在 Swift 类中使用@objc(&#name#&)关键字,这个类可以不需要命名空间即可在 Objective-C 中使用。这个关键字在你迁徙 Objecive-C 代码到 Swift 时同样也非常有用。由于归档过的对象存贮了类的名字,你应该使用@objc(&#name#&)来声明与旧的归档过的类相同的名字,这样旧的类才能被新的 Swift 类解档。
Objective-C 选择器(Selectors)
一个 Objective-C 选择器类型指向一个 Objective-C 的方法名。在 Swift 时代,Objective-C 的选择器被Selector结构体替代。你可以通过字符串创建一个选择器,比如let mySelector: Selector = "tappedButton:"。因为字符串能够自动转换为选择器,所以你可以把字符串直接传递给接受选择器的方法。
import UIKit
class MyViewController: UIViewController {
&&& let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
&&& init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
&&&&&&& super.init(nibName: nibName, bundle: nibBundle)
&&&&&&& myButton.targetForAction("tappedButton:", withSender: self)
&&& func tappedButton(sender: UIButton!) {
&&&&&&& println("tapped button")
注意: performSelector:方法和相关的调用选择器的方法没有导入到 Swift 中因为它们是不安全的。
如果你的 Swift 类继承自 Objective-C 的类,你的所有方法都可以用作 Objective-C 的选择器。另外,如果你的 Swift 类不是继承自 Objective-C,如果你想要当选择器来使用你就需要在前面添加@objc关键字,详情请看。
您可能感兴趣的文章:
上一篇:下一篇:
最 近 更 新
热 点 排 行
12345678910The Swift Programming Language(中文版)
欢迎使用Swift
重要: 本教程系列是针对开发过程中的API或者技术的初步文档。苹果提供该文档旨在为开发者使用该技术和苹果产品上的编程接口提供帮助。这些信息可能会发生变化,依据该文档开发的软件
如果你写过 C 或者 Objective-C 代码,那你应该很熟悉这种形式——在 Swift 中,这行代码就是一个完整的程序。你不需要为了输入输出或者字符串处理导入一个单独的库。全局作用域中的代码会被
Swift -- 语言指南
Swift -- 语言附注
Using Swift with Cocoa and Objective-C(中文版)
Swift被设计用来无缝兼容Cocoa和Objective-C。在Swift中,你可以使用Objective-C的API(包括系统框架和你自定义的代码),你也可以在Objective-C中使用Swift的API。这种兼容性使Swift变成了一个简单、方便
互用性是让Swift和Objective-C相接合的一种特性,使你能够在一种语言编写的文件中访问和使用另一种语言编写的代码。当你准备开始把Swift融入到你的开发流程中时,你应该懂得如何利用互用性来
互用性使得开发者可以定义包含了Objective-C行为的Swift类。编写Swift的class类时,不仅能够子类化Objective-C类,采用Objective-C定义的协议接口,还能利用Objective-C的其它优势功能。
作为对 Objective-C 互用性(互操作性)的一部分,Swift提供快捷高效的方式来处理Cocoa数据类型。Swift 会自动将一些 Objective-C 类型转换为 Swift 类型,以及将 Swift 类型转换为 Objective-C 类型。
使用Cocoa现有的设计模式,有助于开发者编写一款拥有合理设计思路和良好的可扩展性应用的有效方法之一。大部分这些模式都依赖于在Objective-C中定义的类。由于Swift与Objective-C之间存在互用性
作为与Objective-C语言的互操作性的一部分,Swift也保持了一些与C语言的类型和功能的兼容性,如果你的代码有需要,Swift还提供了使用常见的C结构和模式的方式,如果你的代码需要的话。
Swift与Objective-C的兼容能力允许你在同一个工程中同时使用两种语言。你可以用这种叫做“mix and match”的特性来开发基于混合语言的应用。使用Swift的最新特性--“mix and match”,你可以实现应用的一部分功能,并无缝地并入已有的Objective-C的代码中。
迁移工作提供了一个重访现有Objective-C 代码的机会,也可以通过Swift代码来更好的优化app软件架构,逻辑以及性能。直接一点说,你将用先前学到的“mix and match”和“interoperability”这两个章节
Swift开发经验与资源
Swift代码实例
Copyright &酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
本文解决如下问题
ObjC/C 中定义的某个类型、结构体,通过 Bridge Header 或者 Module 对应到 Swift 到底是什么类型
指针间的转换问题
补充之前没解决的一些问题,比如提到CMutablePointer的sizeof是两个字长,那么在函数调用中是如何对应到 C 的指针的?
预备内容:
C/ObjC to Swift 对应规则
以下内容均适合 Objective-C 。第一部分适合 C 。
可导出的类型定义
函数、枚举、结构体、常量定义、宏定义。
结构体定义支持:
typedef struct Name {...} N typedef struct Name_t {...} N struct Name { ... };
其中无法处理的结构体、函数类型、 varargs 定义不导出。预计以后版本会修复。带 bit field 的结构体也无法识别。
类型对应关系
仔细分析发现,诡异情况还很多。基础类型请参考上几篇。
在函数定义参数中:
|类型 | 对应为
|void *|CMutableVoidPointer
|Type *、Type[]|CMutablePointer&Type&
|const char *|CString
|const Type *|CConstPointer&Type&
|const void *|CConstVoidPointer
在函数返回、结构体字段中:
|类型 | 对应为
|const char *|CString
|Type *、const Type *|UnsafePointer&Type&
|void *、const void *|COpaquePointer
|无法识别的结构指针 |COpaquePointer
另外还有如下情况:
全局变量、全局常量(const)、宏定义常量(#define) 均使用var,常量不带set。
结构体中的数组,对应为元祖,例如int data[2]对应为(CInt, CInt),所以也许。。会很长。数组有多少元素就是几元祖。
ObjC 明显情况要好的多,官方文档也很详细。
除了NSError **转为NSErrorPointer外,需要注意的就是:
函数参数、返回中的NSString *被替换为String!、NSArray *被替换为AnyObject[]!。
而全局变量、常量的NSString *不变。
关于CMutablePointer的行为
上回说到CMutablePointer、CConstPointer、CMutableVoidPointer、CConstVoidPointer
四个指针类型的字长是 2,也就是说,不可以直接对应为 C 中的指针。但是前面说类型对应关系的时候, C 函数声明转为 Swift
时候又用到了这些类型,所以看起来自相矛盾。仔细分析了 lldb 反汇编代码后发现,有如下隐藏行为:
在纯 Swift 环境下,函数定义等等、这些类型字长都为 2,不会有任何意外情况出现。
当一个函数的声明是由 Bridge Header 或者 LLVM Module 隐式转换而来,且用到了这四个指针类型,那么代码编译过程中类型转换规则、隐式转换调用等规则依然有效。只不过在代码最生成一步,会插入以下私有函数调用之一:
@transparent func _convertCMutablePointerToUnsafePointer&T&(p: CMutablePointer&T&) -& UnsafePointer&T& @transparent func _convertCConstPointerToUnsafePointer&T&(p: CConstPointer&T&) -& UnsafePointer&T& @transparent func _convertCMutableVoidPointerToCOpaquePointer(p: CMutableVoidPointer) -& COpaquePointer @transparent func _convertCConstVoidPointerToCOpaquePointer(p: CConstVoidPointer) -& COpaquePointer
这个过程是背后隐藏的。然后将转换的结果传参给对应的 C/ObjC 函数。实现了指针大小的字长正确一致。
作为程序员,需要保证调用 C 函数的时候类型一致。如果有特殊需求重新声明了对应的 C 函数,那么以上规则不起作用,所以重声明的函数表示指针时不可以使用这四个指针类型。
虚线表示直接隐式类型转换。其中UnsafePointer&T&可以通过用其他任何指针调用构造函数获得。
CMutablePointer&T&和CMutableVoidPointer也可以通过Array&T&的引用隐式类型转换获得 (&arr)。
椭圆表示类型sizeof为字长,可以用于声明 C 函数。
四大指针可以用withUnsafePointer操作。转换为UnsafePointer&T&。上一节提到的私有转换函数请不要使用。
之前的文章已经介绍过怎么从CString获取String(静态方法String.fromCString)。
从String获取CString也说过, 是用withCString。
也可以从CString(UnsafePointer.alloc(100))来分配空数组。
& 相关主题:属性&提供了更多关于声明和类型的信息。在 Swift 中有两种类型的属性,一种用于声明,一种用于类型。例如,required&属性-当用于类的指定或者便利初始化声明时-指明每个子类都必须实现它的初始化函数。noreturn&属性-当用于函数或者方法的类型时-指明函数或者方法无需返回值。
你可以用字符&@&加上属性名和属性参数来指定一个属性:
@属性名(属性参数)
含有参数的声明属性可以为属性指定更多的信息,可以用于特殊的声明。这些属性参数&被包含在圆括号里,参数的格式由属性决定。
声明属性只能用于声明,当然,你也可以使用&noreturn&属性作为函数或者方法的类型。
assignment
此属性可用于修饰重载复合赋值运算符的函数。这个重载复合赋值运算符的函数必须用&inout&来标记初始输入参数。assignment属性示例参见。
class_protocol
此属性可用于定义类类型协议。
如果你使用&objc&属性的协议, 那么这个协议就隐式含有&class_protocol&属性,你无需显式标记&class_protocol&属性。
此属性可用于内部声明,可以将当前模块的内部模块、子模块或者声明暴露给外部其他模块。如果另一个模块引用了当前模块,那么这个模块就可以访问当前模块中暴露出来的部分。
此属性可用于修饰类或者类的属性、方法或成员下标运算符。用于一个类的时候,表明这个类是不能被继承的。用于类的属性、方法或成员下标运算符的时候,表明这个类的这些成员函数不能在任何子类中重写。
此属性可用于修饰类或者结构体中的存储变量属性,表明这个属性在第一次被访问时,其初始值最多只能被计算和存储一次。lazy&属性示例参见。
此属性用于函数或者方法的声明,表明其函数或者方法相应的类型T是@noreturn T。当一个函数或者方法无需返回其调用者时,你可以用这个属性来修饰其类型。
你可以重写没有标示noreturn属性的函数或者方法。也就是说,你不能够重写有noreturn属性的函数或者方法。当你实现此类型的协议方法时,也有相似的规则。
此属性可用于修饰类中的存储变量属性。被修饰的这个属性的赋值函数是由这个属性值的拷贝组成-由copyWithZone方法返回-而不是这个属性本身的值。此属性类型必须符合NSCopying协议。
NSCopying属性类似于Objective-C中的copy属性。
用于修饰类中的存储变量属性,此类继承于NSManagedObject,表明这个属性的存储和实现是由Core Data基于相关的实体描述实时动态提供的。
此属性可用于能用Objective-C表示的任何声明中-例如,非嵌套的类、协议、类和协议的属性和方法(包括取值函数和赋值函数)、初始化函数、析构函数以及下标运算符。objc属性告诉编译器此声明在Objective-C代码中可用。
如果你使用objc属性修饰类或者协议,它会显式的应用于这个类或者协议中的所有成员。当一个类继承于标注objc属性的另一类时,编译器会显式的为这个类添加objc属性。标注objc属性的协议不能够继承于不含有objc属性的协议。
objc属性可以接受由标识符组成的单个属性参数。当你希望暴露给Objective-C的部分是一个不同的名字时,你可以使用objc属性。你可以使用这个参数去命名类、协议、方法、取值函数、赋值函数以及初始化函数。下面的示例就是ExampleClass的enabled属性的取值函数,它暴露给Objective-C代码的是isEnabled,而不是这个属性的原名。
@objcclass ExampleClass {
var enabled: Bool {
@objc(isEnabled) get {
// Return the appropriate value
您对本文章有什么意见或着疑问吗?请到您的关注和建议是我们前行的参考和动力&&

我要回帖

更多关于 objc.io 中国 的文章

 

随机推荐