【极客班】Swift高级编程一

Swift语言简介

【极客班】Swift高级编程一_第1张图片
image.png

Swift与Object-C语言编译过程对比:
【极客班】Swift高级编程一_第2张图片
image.png

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")
    }
}

类与结构:
类的实例是对象,结构的实例是值;
类的存储是引用类型,堆的存储是值类型:
引用类型:


【极客班】Swift高级编程一_第3张图片
image.png

值类型:


【极客班】Swift高级编程一_第4张图片
image.png

栈与堆的区别:
栈:是存储值类型;无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()
    }   
【极客班】Swift高级编程一_第5张图片
image.png

更多参数与返回值功能:

    //可变数目参数
    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")
    }
【极客班】Swift高级编程一_第6张图片
image.png
  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
}

相等操作符:引用相等,判断对象地址是否相等,仅针对引用类型,不适用于值类型,相等操作符 ===,不等操作符 !==;值相等判断实例值是否相等,自定义类型需重载提供“值比较语义”,相等操作符 ==,不等操作符!==。

你可能感兴趣的:(【极客班】Swift高级编程一)