iOS开发系列--Swift 3.0

概述

从写第一篇Swift文章的时候到现在Swift已经从1.2发展到了今天的3.0,这期间由于Swift目前还在发展阶段并不能向下兼容,因此第一篇文章中的部分代码在当前的Xcode环境中已经无法运行。在WWDC16上Apple公布了Swift3.0,从中可以看出Apple对Swift的重视,以及Swift开源半年以来的进步。尽管对于开发人员来说Swift3.0的变化会令你的程序几乎处处报错,但是试想一下如果Apple没有追求极致的精神又怎么会做出如此多的更改。今天的文章将重点介绍:What‘s new in Swift 3.0?从Swift编译器和标准库两个方面来说明从Swift3.0的变化。

编译器和语法变化

函数或方法参数

  • 调用函数或方法时从第一个参数开始就必须指定参数名

在Swift的历史版本中出现过在调用函数时不需要指定任何函数参数(或者从第二个参数开始指定参数名),在调用方法时则必须从第二个参数开始必须指定参数名等多种情况,而在Swift3.0中不管是函数还是方法都必须从第一个参数开始必须指定参数名(当然可以使用“_”明确指出调用时省略参数)。

// 从第一个参数就必须指定参数名,除非使用"_"明确指出省略参数
func sum(num1:Int,num2:Int)->Int{
    return num1 + num2
}

sum(num1: 1, num2: 2) // old: sum(1,2)或者sum(1, num2: 2)
  • 取消var参数
//func increase(var a:Int){
//    a += 1
//}
// 上面的代码会报错,可改写成
func increase(a:Int){
    var a = a
    a += 1
}
  • inout参数修饰改放到类型前
//func increase(inout a:Int) {
//    a += 1
//}
// 上面的代码会报错,可改为
func increase( a:inout Int) {
    a += 1
}

方法返回值

Swift 3.0 中方法的返回值必须有接收否则会报警告,当然其实主要目的是为了避免开发人员忘记接收返回值的情况,但是有些情况下确实不需要使用返回值可以使用"_"接收来忽略返回值。当然你也可以增加@discardableResult声明,告诉编译器此方法可以不用接收返回值。

struct Caculator {
    func sum(a:Int,b:Int) -> Int {
        return a + b
    }

    @discardableResult
    func func1(a:Int,b:Int) ->Int {
        return a - b + 1
    }
}
let ca = Caculator()
ca.sum(a: 1, b: 2) // 此处会警告,因为方法有返回值但是没有接收
let _ = ca.sum(a: 1, b: 2) // 使用"_"接收无用返回值
ca.func1(a: 1, b: 2) // 由于func1添加了@discardableResult声明,即使不接收返回值也不会警告

可选类型

Swift3.0对于可选类型控制更加严谨,隐式可选类型和其他类型的运算之后获得的是可选类型而不是隐式可选类型。

let a:Int! = 1
let b = a + 1 // 此时强制解包,b是Int型
let c = a // 注意此时c是Int? 在之前的Swift版本中c是Int!

Selector的变化

Selector的改变其实从1.0到3.0经历了多次变化,从最早的@Selector("method:")到现在的#selector(method(param1:))可以说经历了多次修改,好在它变得越来越好,毕竟字符串操作对于语法检查来说是很无助的。

class MyClass {
    @objc func sum(a:Int,b:Int) -> Int {
        return a + b
    }

    func func1(){
        let _ = #selector(sum(a:b:))
    }
}

// old: Swift 2.2
//class MyClass {
//    @objc func sum(a:Int,b:Int) -> Int {
//        return a + b
//    }
//
//    func func1(){
//        let _ = #selector(sum(_:b:))
//    }
//}

协议中的可选方法

在Swift3.0之前如果要定义协议中可选方法,只需要给协议加上@objc之后方法使用optional修饰就可以了,但是Swift3.0中除了协议需要@objc修饰,可选方法也必须使用@objc来修饰。

@objc protocol MyProtocol {
    @objc optional func func1() //old: optional func func1()
    func func2()
}

取消++、--操作符

var d = 1
d++ //报错,可以改写成 d += 1 或者 d = d + 1

取消C风格for循环

//for var i = 0 ;i < 10 ; i += 1 {
//    debugPrint(i)
//}
// 上面的代码会报错,可改写成如下代码
for i in 0  ..< 10  {
    debugPrint(i)
}

SDK类库变化

大家都知道Swift诞生在Objective-C已经发展的相当成熟的情况下,为了保证ObjC开发人员顺利过渡到Swift,也因为Swift处于初级阶段,很多类库和方法命名都尽量和ObjC保持一致,在使用Swift开发iOS应用中处处可以看到ObjC的影子。但是作为一门Modern语言Swift还是做出了改变,从中可以看出日后Swift将彻底摆脱ObjC的影子。这其中包括重新导入Foundation消除类型前缀、方法名去重、函数和方法去C风格等等。

命名

// 1.去掉前缀
let url1 = URL(string: "www.cmjstudio.com")
let isFileURL = url1?.isFileURL //old:url1.fileURL ,现在更加注重语意
let data1 = Data() //NSData

// 2.方法名使用动词,其他名词、介词等作为参数或移除
var array1 = [1,2,3]
array1.append(contentsOf: [4,5,6]) // old:array1.appendContentsOf([4,5,6])
array1.remove(at: 0) // old:array1.removeAtIndex(0)

// 3.不引起歧义的情况下尽量消除重复
let color1 = UIColor.red() // old:var color1 = UIColor.redColor()

// 4.枚举成员首字母变成小写
let label1 = UILabel()
label1.textAlignment = .center // old:label1.textAlignment = .Center

// 5.按钮的Normal状态去掉
let btn1 = UIButton()
btn1.setTitle("hello", for: UIControlState()) // 相当于Normal状态

去C风格

Swift发展初期很多类库的引入依然保持的ObjC风格,但是ObjC由于根出C语言,因此很多操作其实并不是对象和方法操作而是C语言的函数形式。到了Swift3.0之后这一现状将发生变化,全局函数将会变成某些类型的方法;某些常量定义将以某个枚举类型的成员来表示。

let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100)
// 下面的代码将要报错,3.0完全废除这种类C的风格
//let rect1 = CGRectMake(0, 0, 100, 100)

if let context1 = UIGraphicsGetCurrentContext() {
    CGContext.fillPath(context1) // old:CGContextFillPath(context1!)
}

// GCD的改变
let queue = DispatchQueue(label: "myqueue")
queue.async {
    debugPrint("hello world!")
}
// old:
//let queue = dispatch_queue_create("myqueue", nil)
//dispatch_async(queue) {
//    debugPrint("hello world!")
//}

// 相关常量定义被移到枚举内部
NotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: UserDefaults.didChangeNotification, object: nil)
//old:NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: NSUserDefaultsDidChangeNotification, object: nil)

集合API的变化

let array1 = [1,2,3]
let next = array1.index(after: 0)  // old:let start = array1.startIndex let next = start.successor()
let first = array1.first { (element) -> Bool in // 增加新的方法
    element > 1
}

let r = Range(0..<3) //old: let _ = NSRange(location: 0, length: 3)

// 下面的代码必须在控制器中执行,用于遍历当前view及其父视图
for subview in sequence(first: self.view, next: { $0?.superview }){
    debugPrint(subview)
}

新的浮点协议

Float、Double、CGFloat使用了新的协议,提供了提供 IEEE-754标准的属性和方法。

let a = 2 * Float.pi // old: let a = 2 * M_PI
let b = 2.0 * .pi // 注意前面是浮点型,后面可以省略Float

当然Swift3.0中还有一些其他的不常用变化,如果感兴趣可以访问Swift Proposals

从Swift2.2迁移到Swift3.0

可以看出如果要更新到Swift3.0现有项目需要作出大量修改,经过使用之前开源项目TagEditor进行测试,区区十个类文件就出现了一百多个错误,不过好在Xcode 8已经提供了很好用的迁移工具(Xcode:Editor - Convert - To Current Swift Syntax),经过迁移工具转化后仅仅发现两处错误需要手动修正。在使用这个工具的时候大家会看到如下界面:

Swift 2.3?没错Swift2.2和Swift 3.0中间还有个Swift 2.3,Apple也解释了什么是Swift
2.3,其实就是Swift 2.2 + New SDKs。之所以如此是因为Xcode 8目前还是beta版,使用Swift
3.0进行开发的应用还不能提交App Store,因此在Swift 2.2基础上使用新的SDK开发还是有存在必要的。

总结

Swift的每次变化由于对之前的版本乃至上一个版本都不兼容造成每次Swift的升级都显得比较虐心,但是事实上这也是Swift的重大进步。记得之前曾有传闻说Swift3.0的语法和API都会稳定并且向上兼容,但是不久这个消息就破灭了,WWDC上官方也再次证实这个希望可能要到4.0才能实现。但是试想一下:Apple在很短的时间内就固话API对于Swift的发展真的是好事吗?毕竟新特性的加入、更好的语法优化才能让Swift越来越好!总的来说,如果应用要升级到Swift3.0可能要做不同程度的修改,但是这种改动仅仅是语法和SDK的变动并不会消耗太多的工作量,更何况Apple提供了迁移工具。

时间: 2024-10-03 22:12:29

iOS开发系列--Swift 3.0的相关文章

iOS开发系列--Swift进阶

概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用Swift进行iOS开发还是不够的.在这篇文章中将继续介绍一些Swift开发中一些不常关注但是又必备的知识点,以便对Swift有进一步的了解. 访问控制 和其他高级语言一样Swift中也增加了访问控制,在Swift中提供了private.internal.public三种访问级别,但是不同的是Swift中的访问

iOS开发系列--Swift语言

Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了 ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在其中你可以看到C#.Java.Javascript.Python等多种语言的影子.同时在 2015年的WWDC上苹果还宣布Swift的新版本Swift2.0,并宣布稍后Swift即将开源,除了支持iOS.OS X之外还将支持linux. 本文将继续iOS开发系列教程,假设读者已经有了其他语言基础(强烈建

iOS开发系列文章(持续转载中……) 感谢作者,直接连接到作者文章的

C语言 iOS开发系列--C语言之基础知识 iOS开发系列--C语言之数组和字符串 iOS开发系列--C语言之指针 iOS开发系列--C语言之预处理 iOS开发系列--C语言之存储方式和作用域 iOS开发系列--C语言之构造类型 Objective-C iOS开发系列-Objective-C之基础概览 iOS开发系列--Objective-C之类和对象 iOS开发系列--Objective-C之协议.代码块.分类 iOS开发系列-Objective-C之内存管理 iOS开发系列--Objecti

iOS开发系列--C语言之基础知识

概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift 这么看下去还有大量的内容需要持续补充,但是今天我们从最基础的C语言开始,C语言部分我将分成几个章节去说,今天我们简单看一下C的一些基础知识,更高级的内容我将放到后面的文章中. 今天基础知识分为以下几点内容(注意:循环.条件语句在此不再赘述): Hello World 运行过程 数据类型 运算符 常用

iOS开发系列--App扩展开发

概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更新也都是围绕扩展这一主题来进行了的,例如开发的Siri.iMessage Apps其实都是依靠扩展来工作的.在最新的Xcode 8 beta中也增加了众多的Extension 模板帮助开发者更快的实现不同类型的扩展.因此今天有必要介绍一下扩展相关的开发内容. 扩展的生命周期 iOS对于扩展的支持已经

IOS开发语言Swift入门连载---控制流

IOS开发语言Swift入门连载-控制流 Swift提供了类似 C 语言的流程控制结构,包括可以多次执行任务的for 和while 循环,基于特定条件选择执行不同代码分支的if 和switch 语句,还有控制流程跳转到其他代码的break 和continue 语句. 除了 C 语言里面传统的 for 条件递增(for-condition-increment )循环,Swift 还增加了for-in 循环,用来更简单地遍历数组(array),字典(dictionary),区间(range),字符串

iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

iOS开发系列--音频播放.录音.视频播放.拍照.视频录制 转载:http://www.cnblogs.com/kenshincui/p/4186022.html#avFoundationCamera --iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操作都提供了多套API.在今天的文章中将会对这些内容进行一一介绍: 音频 音

iOS开发系列--让你的应用“动”起来

--iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画.动画组.转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等.在今天的文章里您可以看到动画操作在iOS中是如何简单和高效,很多原来想做但是苦于没有思路的动画在iOS中将变得越发简单: CALayer CALayer简介 CALayer常用属性 CALayer绘图 C

iOS开发系列文章(持续更新……)

iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大家交流,新建一个iOS技术交流群,欢迎大家加入:64555322 C语言 IOS开发系列--C语言之基础知识 IOS开发系列--C语言之数组和字符串 IOS开发系列--C语言之指针 IOS开发系列--C语言之预处理 IOS开发系列--C语言之存储方式和作用域 IOS开发系列--C语言之构造类型 Ob