Swift语言简介
Swift与Object-C语言编译过程对比:
Swift的类型系统分为:值类型(基础数值类型、结构、枚举、元组以及特殊类型(String、Array、Dictionary、Set)),引用类型(类、闭包),类型装饰(协议、扩展、泛型)。
学习资源:
Swift官方资源: https://developer.apple.com/swift/resources/
WWDC大会: https://developer.apple.com/wwdc/about/
值类型与引用类型
类型成员:
class MyClass {
//属性
var x:Int
var y:Int
var datas:[Int]=[1,2,3,4,5]
//初始化器
init(x:Int, y:Int){
self.x=x
self.y=y
}
//方法
func print(){
print("\(x), \(y), \(datas)")
}
//下标
subscript(index: Int) -> Int {
get {
return datas[index]
}
set(newValue) {
datas[index]=newValue
}
}
//析构器
deinit{
print("clear up resources")
}
}
类与结构:
类的实例是对象,结构的实例是值;
类的存储是引用类型,堆的存储是值类型:
引用类型:
值类型:
栈与堆的区别:
栈:是存储值类型;无ARC负担,空间大小编译时确定;函数之间通过拷贝值传递;具有局部性,大小有限额,超出会stack overflow。
堆:是存储引用类型对象;分配由程序员手动请求,释放由运行时ARC机制自动释放;函数之间通过值拷贝引用传递;具有全局性,总体无大小限制。
类型成员
属性:属性表达实例状态或类型状态;从属性类别分为:存储属性和计算属性;从可变性分为:变量属性和常量属性;由归属权可以分为:实例属性和类型属性。
存储属性可分为实例属性和静态属性,而计算属性相当于方法:
class Rectangle{
//存储属性
var height:Double = 0
var width:Double = 0
//计算属性-只读属性
var area:Double{
return height*width
}
//静态属性
static var max:Double=10000
}
存储属性也可分为引用存储属性和值存储属性:
//值存储属性
struct SPoint{
var x:Int
var y:Int
}
class RPoint{
var x:Int
var y:Int
static var max=100
init(x:Int,y:Int){
self.x=x
self.y=y
}
}
//值存储属性
struct SPoint{
var x:Int
var y:Int
}
class RPoint{
var x:Int
var y:Int
static var max=100
init(x:Int,y:Int){
self.x=x
self.y=y
}
}
实例存储属性跟随实例存储(值类型在栈上,引用类型在堆上),生存周期跟随实例;静态存储属性的值存储在静态数据区,生存周期从类型加载开始,到类型卸载结束;值存储属性直接内嵌在实例中,引用存储属性通过指针“强引用”堆上的引用类型实例,ARC针对强引用进行计数管理。
方法按归属权分可分为实例方法和类型方法:
//实例方法
func instanceMethod(){
++instanceData
++MyClass.typeData
instanceMethod2()
MyClass.typeMethod()
}
//静态方法(就是类型方法,不能调用实例和实例属性)
static func typeMethod(){
++typeData
//++instanceData
typeMethod2()
//instanceMethod()
}
更多参数与返回值功能:
//可变数目参数
func averageNumber(numbers:Double...)->Double{
var sum=0.0
for item in numbers {
sum+=item
}
return sum / Double(numbers.count)
}
//常量参数 VS. 变量参数
func changeParameter(data1:Int, var data2:Int){
var dataTemp=data1
data2++
dataTemp++
}
//inout参数
func swap(inout a:Int,inout b:Int){
let tempA=a
a=b
b=tempA
}
//返回Tuple类型
func minMax(array: [Int]) -> (min: Int, max: Int){
var currentMin = array[0]
var currentMax = array[0]
for value in array[1.. currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
}
初始化器与析构器
初始化器用于初始化类型实例,是一个特殊的函数,无返回值,初始化过程如下:1.分配内存;2.调用初始化器初始化内存;但是只有实例初始化器,没有类型初始化器。
初始化器主要用于初始化实例存储属性:可以指定默认值,自定义初始化器:
init(){
x=10
y=10
}
init(x:Int, y:Int){
self.x=x
self.y=y
print("init is invoked")
}
convenience init(x:Int, y:Int){
self.init(x:x,y:y,z:0)
}
析构器在实例内存被释放前调用,用于释放实例使用的非内存资源;析构器仅可以定义class,struct和enum不能定义析构器;析构器由运行时根据ARC的释放规则,自动调用,程序员无法手动调用。
deinit{
print("close file...")
}
引用计数管理
对象引用计数增1:新创建对象并赋值给变量,引用计数加1;将对象引用拷贝给其他变量或常量;将对象赋值给其他属性;将对象传递给函数,或者返回值。
对象引用计数减1:将变量赋值为nil;将属性赋值为nil,或者属性所在的对象被释放;传值参数离开函数。
var fs:FileStream?
fs=FileStream() //引用计数:1
fs!.process()
var fs2=fs //引用计数:2
var data=100
var mc: MyClass?
mc = MyClass(myFile:nil)
mc!.myFile=fs //引用计数:3
//调用时引用计数+1 : 4
invoke(fs)
//函数结束引用计数-1 : 3
if data>0 {
var fs3=fs //引用计数:4
} //fs3生存周期结束,引用计数-1: 3
fs=nil //引用计数:2
fs2=nil//引用计数:1
//mc!.myFile=nil
mc=nil //引用计数:0
下标与操作符
下标支持使用索引的方式访问“集合式”实例,例如vector[index];且下标可以类比为“含参的计算属性”,其本质是一对带索引参数的访问器方法(get/set)。
class Vector {
var datas = [Int](count:100,repeatedValue:0)
subscript(index:Int)-> Int{
get{
return datas[index]
}
set {
datas[index]=newValue
}
}
}
重载操作符:除了标准操作符之外,还可以针对自定义类型重载标准操作符;可以重载前缀(prefix)、中缀(infix)、后缀(postfix)操作符,但是前缀和后缀操作符需要加关键词:prefix或postfix;也可以通过将参数设置为inout参数,重载复合赋值操作符,例如:+=,-=;也可以自定义新的操作符,并重载。
//中缀操作符
func + (left: Complex, right: Complex) -> Complex {
return Complex(real: left.real + right.real,
imag: left.imag + right.imag)
}
var c1=Complex(real: 10,imag: 20)
var c2=Complex(real: 100,imag: 200)
var c3=c1+c2
//前缀操作符
prefix func - (data: Complex) -> Complex {
return Complex(real: -data.real, imag: -data.imag)
}
var c4 = -c3
//复合赋值操作符
func += (inout left: Complex, right: Complex) {
left = left + right
}
c1+=c2
//自定义操作符
prefix operator +++ {}
prefix func +++ (inout data: Complex) -> Complex {
data += data
return data
}
相等操作符:引用相等,判断对象地址是否相等,仅针对引用类型,不适用于值类型,相等操作符 ===,不等操作符 !==;值相等判断实例值是否相等,自定义类型需重载提供“值比较语义”,相等操作符 ==,不等操作符!==。