OC与Swift的比较
OC是一门消息传递语言,Swift采用安全的编程模式,并添加新的功能,界面基于Cocoa和Cocoa Touch框架,Swift从1.1到Swift3的升级过程中语法变化较大,苹果承诺Swift 3的升级是最后一个破坏性版本。
一、基础语法的不同
1、类型推测
- 在声明变量时,不需要声明变量的类型,这一点可能会让人觉着Swift不是一门强类型语言。事实上,恰恰相反,Swift不需要制定数据类型的特性依托于Swift强大的类型推测功能。
- Swift可以在变量或常量初始化时判断传递给它的具体值的类型,并把这个类型作为该变量或常量的类型
- 当然, 我们也可以显式的声明该变量或常量的类型
- Swift是类型安全的语言,不论我们是否显式的声明类型,每个常量和变量的类型都是确定的。
2.基本数据类型
2.1 Bool
- Bool类型相比OC中的BOOL更加严格,不再接受非零为真的用法,只有true为真,false为假
2.2 新增元组类型
let info = (name:"GX",age:18,pounds:99.99);
let (infoName,_,_) = info
let infoAge = info.age
let infoPounds = info.2
- 元组是Swift中新增的类型,
- 可以把多个值成员复合成一个值,多个值成员的类型可以不同,把成员值放到括号中,以逗号分隔。
- 元组中每个成员值的前面都有一个默认的索引,我们可以通过索引直接获取元组中各个部分的值
- 我们也可以给每个成员变量命名,获取值的时候直接使用名称调用
- 可以使用元组来定义一些固定形式的信息
- 如果只想获取元组中的重要信息,忽略不相干的信息,可以把元组信息传递给一个新元组,在新元组中只声明接收重要值的值成员,不重要的部分使用下划线“_”表示忽略
2.3 新增可选型
- 可选型也是Swift中新增的类型,可选型用于某些不确定是否有值的情况,有两个返回值,具体的值 和 nil,其中nil表示空值。
- 一个变量被定义为可选型,在没有赋值的情况下会被默认赋值为nil
- 可选型的使用需要解包,四种方式
- 使用“!”强制解包,风险性较高,当值为nil时会导致崩溃
- 使用“??”,该操作符自带解包功能,当值不为nil时,将其解包并返回,当值为nil时,则返回操作符后面的 非可选型 的值。
- 可选绑定 if-let
- 当可选值不为空时,对可选值进行解包,并将值赋给新的变量,新的变量在if内生效
- 可以与其他条件语句一起使用,
- 可选绑定 guard-let-else
- 当可选值不为空时,对可选值进行解包,并将值赋给新的变量,新的变量在guard外层生效
- 相比较if-let 避免了过于深入的嵌套
3.基本运算符
3.1 赋值运算符
- 相比OC,Swift中的赋值运算符不再有Bool类型的返回值
- 避免开发人员在使用“==”时 误用为“=”
3.2 范围
for index in 1...5{
print(index)
}
let index:Int = 10
switch index {
case 1..<4:
print("1..<4")
default:
print("非1..<4")
}
- OC中使用Range函数指定一个起始位置和长度,从而框定一个范围
- Swift中范围使用有两种形式:
- 1...5 表示闭区间[1,5],也就是从1到5的范围
- 1..<5 表示半闭区间[1,5),也就是从1到4
- Swift中的范围通常使用在 for-in循环语句 和 switch控制流的case中
4.集合类型
Array与NSAarray,Dictionary与NSDictionary,Set与NSSet以及String与NSString,都可以无缝切换
4.1 数组
var array:Array<String>=Array<String>()
var array1:[String] = [String]()
- 初始化方法:泛型结构体式的初始化方法
- 第二种初始化方法更为简洁,也是官方推荐的初始化方法
- 通过let var来决定数组是否可变
4.2 集合
- 特点:内部元素不重复
4.3 字典
var dict:Dictionary<String,Any> = Dictionary<String,Any>()
var dict1:[String:Any] = [String:Any]()
- 初始化方法:泛型结构体式的初始化方法
- 第二种初始化方法更为简洁,也是官方推荐的初始化方法
- 通过 let var 决定字典是否可变
5.控制流
5.1 for循环
- for-in,在Swift中凡是遵守了SequenceType协议的类型都可以使用for-in进行遍历。
5.2 guard判断语句
- 作用与可选绑定中的类似,避免了过渡深入的嵌套。
5.3 switch开关语句
6.函数
func sum(_ num1:Int,_ num2:Int)->Int{
return num1 + num2
}
7.闭包
var sumClosure = { (x:Int, y:Int) -> Int in
return x + y
}
var sumClosure1:(_ num1:Int,_ num2:Int)->(Int) = { num1,num2 in
return num1 + num2
}
print(sumClosure(1,2))
print(sumClosure1(3,4))
- 闭包实际是引用类型,所以与OC中的block一样,需要防止出现循环引用,可以使用[weak self] [unowned self]两个方式来切断循环引用
- 应用在两个界面的传值,比如将Cell内部的某些操作,传递给tableView所在的控制器
- 闭包的功能类似于函数嵌套,但是闭包更加灵活
8.泛型
9.函数、闭包、泛型的综合使用
- 闭包放在函数中当作参数使用
- 尾随闭包
- 泛型
- 默认参数
10.类、结构体、枚举
10.1 三者概述
- 三者都拥有属性和方法,枚举本身不能存储数据,但是可以将数据存储在枚举的关联信息中
- 结构体和类可以定义自己的构造方法
- 类是三者中唯一拥有继承属性的。
- 三者类型的主要区别就是值类型和引用类型,其中结构体和枚举传递存储的是复制后的值,而类属于引用类型,传递的是对象的指针
- 三者都可以使用泛型
Tips: 值引用表示使用的时候是使用的复制的值,但不必担心值引用的性能,因为它并不是完全复制,底层依旧是指针。Swift是一门强类型的语言,所以要求值类型的属性必须是类型明确的,当类型明确时,当类型明确时值类型的长度是固定的,复制时间成本时O(1),copies are cheap.
class NewClass{
//创建一个新类
}
struct NewStruct {
//创建一个结构体
}
enum NewEnum{
//创建了一个枚举
}
10.2 枚举
//OC中的枚举
typedef NS_ENUM(NSInteger,Operation) {
OperationDragUp,
OperationInition
};
//Swift中的枚举示例一
enum Operation:String{
case dragUp = "dragUp"
case inition = "inition"
func shouldLoadMore()->Bool{
switch self {
case .dragUp:
return true
case .inition:
return false
}
}
}
//Swift中的枚举示例二
enum Operation1{
case dragUp
case inition
case other(String)
}
11.属性
- 在协议中定义某个计算属性,在协议遵守者遵守这个协议之前,不会增加协议遵守者的 负担。因为系统在保存某个数据结构的时候,只保存它里面的存储属性,而计算属性和方法一样是被统一管理的
12.构造与析构
- swift中有两种构造器,便利构造器和指定构造器,两种构造器的区别
- 指定构造器是默认的初始化方法,一个指定构造器只能调用父类中指定的构造器
-
便利构造器的一个特点,有convenience关键字,并且它想要调用指定构造器必须调用本类中的指定构造器,而不能调用父类中的构造器
- 每个类可以用多个构造器
- 每个类只有一个析构器,deinit,对应OC中的dealloc
13.类型检查、类型转换、类型嵌套
使用is实现类型过检查
使用as实现类型转换
-
swift支持类型嵌套
class EMLFrameListTableHeader: UIView { public class SpecialFeature:NSObject{ var radius:CGFloat = 0.0 } } var specialFeature = EMLFrameListTableHeader.SpecialFeature()
二、混编
1.Swift工程中调用OC
- 将OC头文件导入到桥接文件中,桥接文件的创建方法
-
在Swift中新建OC的代码时会弹框提示建立桥接头文件
SwiftTest-Bridging-Header.h
-
手动创建桥接头文件,命名格式
工程名-Bridging-Header.h
,并手动配置桥接头文件的路径
-
2.OC工程中调用Swift
- 在新建Swift文件之前需要对OC工程做一些设置
-
设置完成后,新建Swift文件,会提示新建header,确认新建
- 在桥接头文件中导入OC文件的文件头,此时就可以在Swift中调用OC了
三、面向协议编程
1.介绍
Swift是一个面向协议的语言,是因为从2.0开始,引入了对协议的扩展的特性。
协议使用步骤如下
- 1.协议的声明,很像其他数据结类型的声明,只不过没有实现而已
- 2.协议的扩展,可以指定扩展的适用对象,在扩展中定义默认的实现
- 3.有类、结构体、或者枚举表示遵守这个协议
- 4.租售协议的数据类型来实现协议中声明的属性和方法,改写免费获得的默认实现
2.代码实操
四、总结 Swift比Objective-C有什么优势?
1、Swift容易阅读,语法和文件结构简易化。
2、Swift更加安全,它是类型安全的语言。
3、Swift代码更少,简洁的语法,可以省去大量冗余代码