前段时间搞了一段时间的swift(swift3.0以前的版本),各种基础控件和知识点的样例demo已完成,还没有来得及喘口气,swift3.0来了,于是就直接用最新的版本来跑了一下工程,build一下立马吓晕了,好几十个错误,这是什么鬼?swift3.0改变这么多吗?虽然可以设置兼容版本,但是swift3.0是最新版,也是以后必须要使用的最低版本(说不定还有swift4.0,swift5.0,谁知道呢),所以我放弃了兼容性的设置,还是直接用swift3.0,于是一个类文件一个类文件的去改,修改中发现虽然语法什么的改变了很多,但是客观来说,这个改变确实是越来越好,越来越规范,越来越简洁。下面就swift3.0的新特性来简单说一下。
一、基础语法知识改动
1. 去除了oc中常用的++、-- 运算符操作,当然还是可以通过+=、-= 来实现相应的功能。
2. 之前使用的for循环格式 for var i = 0;i<100;i++{ //code here }已被遗弃,取而代之的是 for i in 1...100{//code here }、(1...10).forEach {//code here}
3. 所有的函数参数都有带上形参标签,3.0之前的版本一般是从第二个参数开始才带参数标签,3.0以后第一个也要加上形参标签,这个感觉有点增加工作量,其实从安全角度考虑还是值得的。
let sum = add(a: 2, b: 10)
func add(a:Int, b:Int) -> Int{
return a + b
}
4. 移除了 NS 前缀,替换为下面的展示形式
let file = Bundle.main.path(forResource: "demo", ofType: "json")
let url = URL(fileURLWithPath: file!)
let data = try! Data(contentsOf: url)
let json = try! JSONSerialization.jsonObject(with: data)
print(json)
5.数组排序函数的改变,过去数组排序的两个方法:sortInPlace() 和 sort(),现在分别改名成 sort() 和 sorted()
sort() 是直接对目标数组进行排序。sorted() 是返回一个排序后的数组,原数组不变。
var array1 = [1, 5, 3, 2, 4]
array1.sort()
print(array1) //[1, 2, 3, 4, 5]
var array2 = [1, 5, 3, 2, 4]
let sortedArray = array2.sorted()
print(array2) //[1, 5, 3, 2, 4]
print(sortedArray) //[1, 2, 3, 4, 5]
6. 数组的反转和遍历的改变,过去 reverse() 方法实现数组反转,enumerate() 方法实现遍历。现这两个方法都加上 ed 后缀(reversed、enumerated)
for i in (1...100).reversed() {
print(i)
}
let array = [1, 5, 3, 2, 4]
for (index, value) in array.enumerated() {
print("\(index + 1) \(value)")
}
7. 枚举成员变成小写字母开头
Swift 3.0 将枚举成员当做属性来看,所以现在使用小写字母开头而不是以前的大写字母,这种写法更符合驼峰式的编写规范。
.system //过去是:.System
.touchUpInside //过去是:.TouchUpInside
.fillStroke //过去是:.FillStroke
.cgColor //过去是:.CGColor
二、UI层面的改动(简要的举例一下,更多的自己在工程中体验,都有提示输出的)
swift3.0在UI的层面改动了不少,不过相对之前的版本来说,这个改动更加简洁,更加符合使用习惯。
1. 移除了多余的API词语,而且将之前的大写开头的(比如.Normal)改了了小写形式(.normal)更加符合我们以往oc的规范和习惯。
UIApplication .sharedApplicaton 改为UIApplication .shared
NSTextAlignmentCenter改为NSTextAlignment.center
UIColor.blueColor() 改为 UIColor.blue
button.setTitle(forState) 改为 button.setTitle(for)
button.addTarget(action, forControlEvents) 改为 button.addTarget(action, for)
arr.minElement() 改为 arr.min()
arr.maxElement() 改为 arr.max()
attributedString.appendAttributedString(anotherString) 改为 attributedString.append(anotherString)
names.insert("Jane", atIndex: 0) 改为 names.insert("Jane", at: 0)
NSBundle.mainBundle() 改为 Bundle.main
UIDevice.currentDevice() 改为 UIDevice.current
NSData(contentsOfURL) 改为 Data(contentsOf)
NSJSONSerialization.JSONObjectWithData() 改为 JSONSerialization.jsonObject(with)
2. 取消了CGRectMake(0,0,100,100)方法,用CGRect(x:0 ,y:0,width:100,height:100)替换,取消了CGPointMake(0, 0),用CGPoint(x: 0, y: 0)替换,取消了CGSizeMake(20, 20),用CGSize(width: 20, height: 20)替换
3.特别要提醒的是函数的方法名(无参和有参)
之前对按钮添加事件的时候可以直接用字符串来作为函数的方法名,例如,backBtn.addTarget(self, action: “backAction”, forUIControlEvents: .touchUpInside),3.0以后就取消了这种定义方式,而是改成了#selector的方式,backBtn.addTarget(self, action: #selector(backAction), for: UIControlEvents.touchUpInside),上面说的是对于没有参数的方法而言,对于带有参数的方法,这里就要注意了,之前对按钮添加有参的事件方法可以是backBtn.addTarget(self, action: “backAction:”, forUIControlEvents: .touchUpInside)或backBtn.addTarget(self, action: #selector(backAction:), forUIControlEvents: .touchUpInside),3.0以后这两个方式都被取消了,而是用backBtn.addTarget(self, action: #selector(backAction(_:)), for: UIControlEvents.touchUpInside)
如果是对于手势操作,函数中的参数定义要和实现中的保持一致
//长按监听
let longPress=UILongPressGestureRecognizer(target:self,
action:#selector(longPressDid(sender:)))
self.view.addGestureRecognizer(longPress)
//长按手势,
func longPressDid(sender: UILongPressGestureRecognizer){
if sender.state == .began {
print("长按响应开始")
} else {
print("长按响应结束")
}
}
开关控件和日期控件的选择事件的命名同上。
三、GCD方面的改变
GCD方面的语法形式改动的也不小,之前的版本和OC的风格还是比较相近的,但是swift3.0中变化很大,dispatch 的全局函数不再写为下划线风格的名称了,它变成了一个更符合 Swift 风格的 DispatchQueue 。
1.主线程
过去是通过 dispatch_get_main_queue ( ) 来获取主线程,现在是用 DispatchQueue .main,只需要在线程后边使用.async{ } 即可,
DispatchQueue.main.async {
//code here
}
2.优先级 名称
过去GCD 的默认队列优先级有四个:
• DISPATCH_QUEUE_PRIORITY_HIGH
• DISPATCH_QUEUE_PRIORITY_DEFAULT
• DISPATCH_QUEUE_PRIORITY_LOW
• DISPATCH_QUEUE_PRIORITY_BACKGROUND
swift3.0 中,这四个优先级的名字更加简洁易懂:
• .userInitialted (对应之前的DISPATCH_QUEUE_PRIORITY_HIGH)
• .default(对应之前的DISPATCH_QUEUE_PRIORITY_DEFAULT)
• .utility(对应之前的DISPATCH_QUEUE_PRIORITY_LOW)
• .background(对应之前的DISPATCH_QUEUE_PRIORITY_BACKGROUND)
3. 获取一个队列
swift3.0使用 DispatchQueue.global ( ) 获取一个系统的队列(系统自带的全局并发队列),这样的话获取的就是默认 .default优先级的队列了,如果要获取其他优先级的队列,就使用DispatchQueue.global(qos:.userInitiated),最后,我们使用 . async{} 来执行代码:
DispatchQueue.global(qos: .userInitiated).async {
//code here
}
4. 创建一个队列
直接用 DispatchQueue 的初始化器来创建一个队列。最简单直接的办法是这样:
let queue = DispatchQueue(label: "myBackgroundQueue"){
//code here
}
你可以指定优先级以及队列类别:
let queue = DispatchQueue(label: "myBackgroundQueue", qos: .userInitiated, attributes: .concurrent)
{
//code here
}
5. 队列组
对于组,可以使用这样的语法直接创建一个组:
let group = DispatchGroup()
至于使用,则是这样的:
let group = DispatchGroup()
let queue = DispatchQueue(label: "myBackgroundQueue")
queue.async(group:group) {
print("background working")
}
那么,如果有多个并发队列在同一个组里,我们需要它们完成了再继续呢?
group.wait()
6. 指定时间后执行操作
这个大家知道在swift3.0之前实现这个功能还是比较繁琐的,特别是哪些系统宏的使用,但是swift3.0以后,这个实现就变的非常简单了,只需如下代码即可。
//下面的x就是你想延迟执行的秒数
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + x) {
//code here
}
swift3.0的变动还有很多细节方面的,这里就不一一陈述了,具体的变化还是要在实际使用时才能更好的体会到。