Swift和OC共用一套运行时环境,Swift的类型可以桥接到OC,反之亦然。两者可以互相引用混合编程。
Swift新出的一些新兴概念,这些是OC没有的,比如泛型、元组等。
优点
- 简洁的语法,性能较好
swift比OC精简,整个项目少了.h文件,以及头文件的引入,效率提升1.3倍。 - swift更加安全
类型安全的语言,可选类型,强制解包等 if let,guard let。 - 定义变量简单
定义变量不区分整型,浮点型等,变量使用var,常量使用let。 - 函数式编程的支持
filter,map,reduce,flatMap,compactMap等。
swift本身提供了对函数式编程的支持,OC本身是不支持的,需要引入ReactiveCocoa这个库才支持。 - 可视化互动效果
开发工具带来了Xcode Playgrounds功能,该功能提供强大的互动效果,能让swift源代码在撰写过程中实时显示出其运行结果。 - 精准报错
报错的时候直接显示报错行。
缺点
- 版本不稳定。
- 使用比例偏低。
- swift开源库较少,不过正在改变中。
- App体积变大,多出5~8M,由于版本不稳定,iOS系统库中并没有包含swift的运行库,反而是每个App都要包含其对应的swift运行库。
- 公司使用比例不高,很多公司以稳为主,很少一些在进行混合开发,更少一些是swift开发。
- 纯swift的运行时和OC有本质区别,一些OC中强大的运行时功能,在纯swift中变无效了。
1. swift可选类型
swift引入可选类型,用于处理变量值不存在的情况,Optionals类似于OC中指向nil的指针,但是适用于所有数据类型,而非仅仅局限于类,Options相比于OC中nil指针,更加安全和简明,并且也是Swift诸多强大功能的核心。
2. swift中泛型
解决代码复用问题
例如两个方法类似,主要是参数类型的区别
func isIntEqual(x: Int, y: Int) -> Bool {
return x == y
}
func isStringEqual(x: Int, y: Int) -> Bool {
return x == y
}
可以利用泛型合并一下:
func isObjEqual(x: T, y: T) -> Bool {
return x == y
}
当使用时,如果将两个不同类型的数进行比较,编译器会马上提醒我们,从而快速避免这种情况。
3. 访问权限变更
swift新增两种权限,fileprivate,open,权限更细化。
open、public、internal(默认)、fileprivate、private
开放权限依次从大到小
- open:可以被任何人使用,包括override和继承。
- public:可以被任何人访问,但其他module中不可以被override和继承,在本module中可以被override和继承。
- internal:系统默认访问级别,internal修饰符可写可不写,访问级别所修饰的属性或方法在源代码所在的整个模块都可以访问。
如果是框架或者库代码,则整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
如果是App代码,也是在这个App代码,也是整个App内部可以访问。 - fileprivate:表示这个元素的访问权限为文件内私有,包括extension时可以访问
- private:只在当前类或结构体的作用域可访问。
4.Swift便捷的函数式编程
4.1、map
var values = [1, 3, 5, 7]
let result = values.map( { (element) -> Int in
return element * 2
}) // [2, 6, 10, 14]
4.2、filter
var result = [1, 3, 5, 7, 9]
let flattenResult = result.filter{ $0 % 3 == 0 }
// [3, 9]
4.3、reduce
var result = [1, 3, 5]
let initialResult = 10
var reduceResult = values.reduce(initialResult, combine: { $0 + $1 })
print(reduceResult) // 10 + 1 + 3 + 5 = 19
4.4、flatMap(合并集合)
let arrayNumbers = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(arrayNumbers.flatMap{ $0 }) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(arrayNumbers.flatMap{ $0.map{ $0 *10 } }) // [10, 20, 30, 40, 50, 60, 70, 80, 90]
print(arrayNumbers.flatMap{ $0.filter{ $0 > 4 } }) // [5, 6, 7, 8, 9]
4.5、compactMap(过滤空值)
let names: [String?] = ["zhangsan", nil, "lisi", "wangwu", nil, "zhaoliu"]
print(names.count) // 6
print(names.compactMap{ $0 }) // ["zhangsan", "lisi", "wangwu", "zhaoliu"] 过滤了空值
// 打印不是空值的字符串的个数
print(names.compactMap{ $0?.count }) // [8, 4, 6, 7]
5. Swift独有的元组类型
元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求相同类型。
var value = (Int, String) = (x: 15, y: "abc")
6. Swift中使用let定义常量,var定义变量
使用常量,更加安全,不能够被修改。
在需要对对象进行修改的时候,只能用var修饰。
7. 细节使用区别
- swift不区分.h和.m,一个类只有.swift一个文件,所以整体的文件数量比起OC有一定的减少。
- swift句尾不需要分号,除非想在一行中写三行代码,加分号隔开。
- swift数据类型都会自动判断,只区分常量let和变量var。
- 强制类型转换格式不同,OC强转:(Int)a。swift:Int(a)。
- 关于BOOL类型更加严格,swift不再是OC的非0就是真,而是true才是真,false才是假。
- swift循环语句中必须加{},就算只有一行也要加。
- swift的swift语句后面可以跟各种数据类型,如Int,字符串都行,并且里面不需要写break。
- swift if后的括号可以省略,if a > b {},而OC里if后面必须写括号。
- swift打印用 print("")打印变量可以 print("(value)")不用像oc一样写很多%d,%@等。
- swift的【Any】可以代表任意类型的值,无论是类、枚举、结构体还是其它swift类型,这个对应OC中的【id】类型。