Swift和Objective-C可以进行互操作,也就是说可以在Objective-C项目中使用Swift代码,反过来也可以。当然,这种互操作之间最重要的是可以在Swift中调用Objective-C的接口,毕竟目前绝大部分接口都是通过Objective-C提供的。

初始化

在Swift中实例化一个Objective-C的类时,可以用Swift语法调用它的一个初始化器。Objective-C的初始化方法被分割成关键字。例如“initWith”变成“init”,而剩下的部分作为方法的参数名。

Objective-C的代码:

UITableView *myTableView = [[UITableView alloc] initWithFrame: CGRectZero style: UITableViewStyleGrouped];

对应的Swift代码为:

let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

在Swift中不需要调用alloc方法,它会自动处理对象的创建功能。注意:Swift不会显式的调用init方法。

定义变量或者常量的时候,可以省略它的类型,Swift会自动识别。

let myTextField = UITextField(frame: CGRect(0.0, 0.0, 200.0, 40.0))

为了方便起见,Objective-C的工厂方法被映射为Swift中的初始化器。例如:

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)

属性访问

在Objective-C和Swift中访问属性都是使用点操作符。

myTextField.textColor = UIColor.darkGrayColor()
myTextField.text = "Hello world"if myTextField.editing {myTextField.editing = false}

访问和设置属性的时候不需要使用圆括号,上面darkGrayColor之所以有括号,是因为调用的是UIColor的类方法,而不是属性。

Objective-C中不需要参数并且有一个返回值的方法,可以被当作隐含的获取方法(getter),从而使用点操作符。但是在Swift中点操作符只能访问Objective-C中使用@property定义的属性。

方法调用

在Swift中使用点操作符调用Objective-C中的方法。

Objective-C的方法在Swift中调用的时候,它的第一部分成为Swift的基本方法出现在括号之前。然后函数的第一个参数没有名字,剩下的部分作为Swift函数对应的参数名称。
Objective-C语法:

[myTableView insertSubview: mySubview atIndex: 2];

Swift代码:

myTableView.insertSubview(mySubview atIndex: 2)

调用无参的方法:

myTableView.layoutIfNeeded()

兼容id类型

Swift包含一个叫AnyObject的协议,与Objective-C中的id类似,可以表示任意类型的对象。AnyObject协议允许你在利用无类型对象的灵活性的同时保持类型安全。
你可以给AnyObject类型的变量赋任意的值:

var myObject: AnyObject = NSData()

可以直接方法AnyObject类型对象的任意属性和方法,而不需要进行强制类型转换。

let dateDescription = myObject.descriptionlet timeSinceNow = myObject.timeIntervalSinceNow

由于AnyObject类型的变量的类型需要到运行时才能确定,因此可能会导致不安全的代码。特别是你可以访问一个不存在的属性或者方法,它只是在运行时报错。

myObject.characterAtIndex(5)
//crash, myObject doesn't respond to that method

在进行类型转换的时候,不一定转换成功,因此Swift返回的是一个Optional值。你可以检查是否转换成功。

let userDefaults = NSUserDefaults.standardUserDefaults()let lastRefreshDate: AnyObject? = userDefault.objectForKey("LastRefreshDate")if let date = lastRefreshDate as? NSDate {println("\(date.timeIntervalSinceReferenceDate)")
}

如果你能够确定对象的类型,并且不为nil,可以使用as操作符进行强制转换。

let myDate = lastRefreshDate as NSDatelet timeInterval = myDate.timeIntervalSinceReferenceDate

nil对象

Objective-C中使用nil来表示引用一个空对象(null)。Swift中所有的值都不会为nil。如果需要表示一个缺失的值,可以使用Optional。

由于Objective-C不能确保所有值都非空,因此Swift将Objective-C中引入的方法的参数和返回值都用Optional表示。在使用Objective-C对象之前,应该检查它们是否存在。

扩展

Swift的扩展与Objective-C的类别有点类似。扩展能够为已有类、结构体、枚举等增加行为。

下面是给UIBezierPath添加扩展:

extension UIBezierPath {    class func bezierPathWithTriangle(length: Float, origin: CGPoint) -> UIBezierPath {        let squareRoot = Float(sqrt(3))        let altitude = (squareRoot * length) / 2let myPath = UIBezierPath()myPath.moveToPoint(orgin)myPath.addLineToPoint(CGPoint(length, origin.x))myPath.addLineToPoint(CGPoint(length / 2, altitude))myPath.closePath()return myPath}
}

可以使用扩展增加属性(包括类属性或静态属性)。不过这些属性只能是通过计算得来,而不能进行存储。下面给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

使用扩展可以在不创建子类的情况下让现有的类响应某个协议。需要注意的是,扩展不能覆盖已有的方法和属性。

闭包

Objective-C中的Block 被自动导入为Swift的闭包。例如:

void (^completionBlock)(NSData *, NSError *) = ^(NSData *data, NSError *error) {    /* ... */}

在Swift 中对应为:

let completionBlock: (NSData, NSError) -> void = {data, error in /* ... */}

Swift的闭包和Objective-C中的Block是兼容的,可以在Swift中给Objective-C的方法传递闭包来代替Block对象。

闭包和Block对象有一点不同,里面的变量是可变的,也就是说与__block修饰的变量行为相同。

对象比较

Swift中有两种对象比较的方式。第一种是相等(==)(equality),用来比较两个对象的内容是否相同。第二种是恒等(===)(identity),比较两个变量或者常量是否引用同一个对象。

NSObject只能比较是否引用了同一个对象(恒等),如果要比较内容是否相同,应该实现isEqual:方法。

Swift类型兼容性

定义一个继承自NSObject或者其他Objective-C的类,它自动与Objective-C兼容。如果你不需要将Swift对象导入Objective-C代码的话,没必要关注类型的兼容性。但是如果在Swift中定义的类不是Objective-C类的子类,在Objective-C中使用的时候,需要用@objc进行说明。

@objc使得Swift的API可以在Objective-C和它的运行时中使用。当使用@IBOutlet@IBAction或者@NSManaged等属性时,自动添加@objc属性。

@objc还可以用来指定Swift中的属性或方法在Objective-C中的名字,比如Swift支持Unicode名字,包括使用中文等Objective-C不兼容的字符。还有给Swift中定义的函数指定一个Selectorde名字。

@objc(Squirrel)class 长沙戴维营教育 {@objc(hideNuts:inTree:)func 欢迎光临(Int, 姓名: String) {        /* ... */}
}

@objc(<#name#>)属性作用在Swift的类上时,这个类在Objective-C的使用不受命名空间的限制。同样,在Swift中解归档Objective-C归档的对象时,由于归档对象中存放有类名,因此需要在Swift中用@objc<#name>说明Objective-C的类名。

Objective-C选择器(Selector)

Objective-C的选择器是方法的一个引用。在Swift中对应的是Selector结构体。使用字符串字面量可以构建一个选择器对象,如let mySelector: Selector = "tappedButton:"。由于字符串字面常量可以自动转换为选择器对象,因此可以在任何需要传递选择器的地方使用字符串字面常量。

import UIKitclass 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:以及相关的调用选择器的方法没有被引入到Swfit中来,因为它们不是完全安全的。

如果Swift类继承自Objective-C的类,则它里面的方法和属性都能够作为Objective-C的选择器使用。而如果不是Objective-C的子类,需要使用@objc属性修饰,这个在前面的Swift类型兼容性中有描述。

转载于:https://blog.51cto.com/diveinedu/1623220

Swift与Objective-C API交互相关推荐

  1. 前后端API交互如何保证数据安全性?

    本文转载自公众号: 猿天地 1.前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC端的软件,只要是 ...

  2. swift中WKWebView和JS交互实现

    在Swift中加载HTML网页有两个view,分别是WKWebView和UIWebView,这里我使用的是WKWebView 这里分享一下我的写法: 1.定义变量WKWebView: lazy var ...

  3. 双方API交互:签名及验证-- (AK/SK)认证的实现

    接口交互提供一个开发的接口地址和接口文档, 知道了url,知道了参数怎么传,坏人就来了: 1.可以任意请求任意参数值,调用你的接口. 2.频繁请求.恶意攻击,让你一直处理接口对应的业务逻辑. 3.拦截 ...

  4. Swift调用Objective C的FrameWork

    很多Github的库经过很多年的发展,源码都是OC写的,,所以,用Swift调用OC的库就是开发中难免遇到的的一个问题,本文以AFNetworking为例,讲解如何跨语言调用. 第一步 创建一个空的工 ...

  5. 初用vue2写一个超简陋知乎日报(不与知乎日报api交互)超详细记录

    刚学vue,文档还没看全,写一个超简陋版知乎练手记录,因为css不太会所以很难看 会计量超详细记录,主要为做记录 包含左抽屉式导航,下拉更新,上拉加载,轮播 用到: Font Awesome muse ...

  6. swift - xcode10 - 点击事件交互BUG - (手势和button的addTarget方法)

    1. 现象 button 点击闪退:没有任何原因 ,在听云检测上,显示 BUG2: 手势 没有任何作用,哪怕设置  isUserInteractionEnabled 和isEnabled 为true ...

  7. Openstack Swift 原理、架构与 API 介绍

    OpenStack Swift 开源项目提供了弹性可伸缩.高可用的分布式对象存储服务,适合存储大规模非结构化数据.本文将深入介绍 Swift 的基本设计原理.对称式的系统架构和 RESTful API ...

  8. Introducing Swift(Swift介绍及其API)

    Home / OpenStack Swift / OpenStack Swift Architecture http://www.swiftstack.com/openstack-swift/arch ...

  9. Swift vs. Objective-C:未来看好Swift的十个理由

    是时候使用易入手又全面的 Swif 语言为 iOS 和 mac OS X 做应用开发了. 虽然编程语言不会那么容易消逝,但坚持衰落范例的开发小组正在这么做.如果你正为移动设备开发应用程序,并且你还没有 ...

最新文章

  1. 2014.4新版uboot启动流程分析
  2. Python的sorted函数应用
  3. 朗讯项目的一个概括总结.
  4. python使用循环结构计算10_十二、 python中的循环结构
  5. .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法
  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
  7. 【转】系统管理员之企业生存守则
  8. Pytorch使用Tensorboard记录loss曲线 (Tensorboard学习二)
  9. JDK Windows安装
  10. 网站运营模式之行业网站分析
  11. Java面试题(三)TCPIP协议
  12. DeepLog:基于系统日志使用深度学习方法做异常检测和诊断
  13. win10无法新建文件夹怎么办?(已解决)
  14. powergui 中“varargout“ 时,未对一个或多个输出参数赋值。
  15. 极品PS动作繁星散射GIF动画
  16. 3分钟教会你解决SVN文件夹没有绿勾和红色感叹号的问题
  17. 重心法选址 matlab程序,Excel重心法选址计算题的详细步骤
  18. 湘鄂情更名后携手中科院瞄准大数据
  19. 【NISP一级】考前必刷九套卷(五)
  20. 【算法】【动态规划篇】第3节:数字三角形问题

热门文章

  1. 解决Android Studio内代码乱码
  2. java绘制地球绕太阳转_Unity3D 公转小案例:地球围绕太阳转
  3. CSS学习16之层级
  4. go语言打印日期_判定是否掌握Go语言的最重要标准:对并发的掌握
  5. php内核函数手册,深入理解PHP内核(五)函数的内部结构,深入理解内部结构
  6. 一份好的简历应该是这样的(This Is What A GOOD Resume Should Look Like)
  7. 【C++】45.尽量不要在构造函数中调用函数或开启线程
  8. 如何评价rcnn、fast-rcnn和faster-rcnn这一系列方法?
  9. Vue.js 单文件组件
  10. Spring实现AOP的4种方式