Swift与Objective-C API交互
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交互相关推荐
- 前后端API交互如何保证数据安全性?
本文转载自公众号: 猿天地 1.前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC端的软件,只要是 ...
- swift中WKWebView和JS交互实现
在Swift中加载HTML网页有两个view,分别是WKWebView和UIWebView,这里我使用的是WKWebView 这里分享一下我的写法: 1.定义变量WKWebView: lazy var ...
- 双方API交互:签名及验证-- (AK/SK)认证的实现
接口交互提供一个开发的接口地址和接口文档, 知道了url,知道了参数怎么传,坏人就来了: 1.可以任意请求任意参数值,调用你的接口. 2.频繁请求.恶意攻击,让你一直处理接口对应的业务逻辑. 3.拦截 ...
- Swift调用Objective C的FrameWork
很多Github的库经过很多年的发展,源码都是OC写的,,所以,用Swift调用OC的库就是开发中难免遇到的的一个问题,本文以AFNetworking为例,讲解如何跨语言调用. 第一步 创建一个空的工 ...
- 初用vue2写一个超简陋知乎日报(不与知乎日报api交互)超详细记录
刚学vue,文档还没看全,写一个超简陋版知乎练手记录,因为css不太会所以很难看 会计量超详细记录,主要为做记录 包含左抽屉式导航,下拉更新,上拉加载,轮播 用到: Font Awesome muse ...
- swift - xcode10 - 点击事件交互BUG - (手势和button的addTarget方法)
1. 现象 button 点击闪退:没有任何原因 ,在听云检测上,显示 BUG2: 手势 没有任何作用,哪怕设置 isUserInteractionEnabled 和isEnabled 为true ...
- Openstack Swift 原理、架构与 API 介绍
OpenStack Swift 开源项目提供了弹性可伸缩.高可用的分布式对象存储服务,适合存储大规模非结构化数据.本文将深入介绍 Swift 的基本设计原理.对称式的系统架构和 RESTful API ...
- Introducing Swift(Swift介绍及其API)
Home / OpenStack Swift / OpenStack Swift Architecture http://www.swiftstack.com/openstack-swift/arch ...
- Swift vs. Objective-C:未来看好Swift的十个理由
是时候使用易入手又全面的 Swif 语言为 iOS 和 mac OS X 做应用开发了. 虽然编程语言不会那么容易消逝,但坚持衰落范例的开发小组正在这么做.如果你正为移动设备开发应用程序,并且你还没有 ...
最新文章
- 2014.4新版uboot启动流程分析
- Python的sorted函数应用
- 朗讯项目的一个概括总结.
- python使用循环结构计算10_十二、 python中的循环结构
- .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
- 【转】系统管理员之企业生存守则
- Pytorch使用Tensorboard记录loss曲线 (Tensorboard学习二)
- JDK Windows安装
- 网站运营模式之行业网站分析
- Java面试题(三)TCPIP协议
- DeepLog:基于系统日志使用深度学习方法做异常检测和诊断
- win10无法新建文件夹怎么办?(已解决)
- powergui 中“varargout“ 时,未对一个或多个输出参数赋值。
- 极品PS动作繁星散射GIF动画
- 3分钟教会你解决SVN文件夹没有绿勾和红色感叹号的问题
- 重心法选址 matlab程序,Excel重心法选址计算题的详细步骤
- 湘鄂情更名后携手中科院瞄准大数据
- 【NISP一级】考前必刷九套卷(五)
- 【算法】【动态规划篇】第3节:数字三角形问题
热门文章
- 解决Android Studio内代码乱码
- java绘制地球绕太阳转_Unity3D 公转小案例:地球围绕太阳转
- CSS学习16之层级
- go语言打印日期_判定是否掌握Go语言的最重要标准:对并发的掌握
- php内核函数手册,深入理解PHP内核(五)函数的内部结构,深入理解内部结构
- 一份好的简历应该是这样的(This Is What A GOOD Resume Should Look Like)
- 【C++】45.尽量不要在构造函数中调用函数或开启线程
- 如何评价rcnn、fast-rcnn和faster-rcnn这一系列方法?
- Vue.js 单文件组件
- Spring实现AOP的4种方式