swift 结构体

本人已迁移博客至掘进,以后会在掘进平台更新最新的文章也会有更多的干货,欢迎大家关注!!!https://juejin.im/user/588993965333309

 

在OC概念中经常提到的是类,但是在swift底层声明中已经大部分使用了struct结构体,下面我们就来讲解一下swift中的结构体.

 

一、类与结构体的区别

  1. 语义
  • 类: 引用类型(引用语义),需要自己管理引用计数,引用值的变化
  • 结构体:可以被直接持有及访问,不会被引用,但是会被复制.也就是说,结构体的持有者是唯一的

  拓展:

    byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。

    string,类等皆为引用类型。

    值类型变量声明后,不管是否已经赋值,编译器为其分配内存。此时该值存储于栈上;int i=10;执行之前为默认一个值0。

    引用类型定义时在栈上开辟一个空间用来存放其在堆上的地址,当赋值或者实例化时候就会在堆上开辟一个空间,然后把堆中的地址存放在栈中,这时候栈就存放了其地址。

 

  2.  内存管理方式

  • 类: 类的实例只能通过引用来间接地访问,类能有很多个持有者
  • 结构体: 可以被直接持有及访问,不会被引用,但是被复制,也就是说,结构体的持有者是唯一的

 

  3.  共享代码

  • 类: 通过继承来共享代码
  • 结构体(以及枚举): 不能被继承,想要在不同的结构体或者枚举之间共享代码,我们需要使用不同的技术,比如像是组合、泛型以及协议拓展

 

 

二、结构体

结构体为值类型

值类型意味着一个值变量被复制时,这个值本身也会被复制,而不只限于对这个值的引用的复制.

let a = 12
let b = a 
a += 1 
print (a) // 13
print (b) // 12
b的值没有根据a的值进行改变

而在swift中结构体的功能也被扩大化了,基本拥有了和类差不多的功能:

  • 定义属性
  • 定义方法
  • 定义getter和setter
  • 可以定义初始化器来设置初始状态
  • 实现扩展的功能
  • 遵循协议,并实现协议的方法
  • 结构总是被复制,并且不使用引用计数

类具有结构不具备的附加功能:

  • 继承允许一个类继承另一个类的特征
  • 类型转换使你能够在运行时检查和解释类实例的类型
  • 初始化器使一个类的实例能够释放它所分配的任何资源
  • 引用计数允许多个引用到一个类实例

 

1.定义结构体和类,并且为其添加变量和方法

struct Resolution {
    var width = 0
    var height = 0
    
    func resolutionFun() {
        print("method of struct Resolution")
    }
}

class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
    
    func VideoMode() {
        print("method of class VideoMode")
    }
}

 

2.类和结构体的初始化

let object Name = Class Name()
let  variable Name = Struct Name()


let someResolution = Resolution()
let someVideoMode = VideoMode()

访问属性

Swift中访问属性使用的是链式结构,访问属性的时候使用 .

print("The width of someResolution is \(someResolution.width)")
print("The width of someVideoMode is \(someVideoMode.resolution.width)")

结构体的初始化

struct Resolution {
    var width = 0
    var height = 0
}

let resolution = Resolution(width:100,height:120)
print("width:\(resolution.width),height:\(resolution.height)")
结果:
width:100,height:120

首先要知道初始化器是系统本身的方法,我们只能去重写或者重载它

重载就是将父类已有的方法通过扩充参数的形式重新定义一遍。

class VideoMode {
    var _name: String
    
    init(){
        _name = "Jin"
    }
    
    init(name:String){
        _name = name;
    }
    
}

let videoModeNormal = VideoMode()
print("name:\(videoModeNormal._name)")
let videoModeCustom = VideoMode(name: "Jack")
print("name:\(videoModeCustom._name)")
结果:
name:Jin
name:Jack

当然,struct的初始化方法也是可以这样实现的:

struct Resolution {
    var width: Double
    
    init(){
        width = 100
    }
    
    init(width:Double){
        self.width = width;
    }
    
}

let resolutionNormal = Resolution()
print("width:\(resolutionNormal.width)")
let resolutionCustom = Resolution(width: 120)
print("width:\(resolutionCustom.width)")
结果:
width:100.0
width:120.0

 

类和结构体的选择

 结构体实例通过值传递,类实例通过引用传递.这意味两者通过不同的任务,当你在考虑一个项目数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体.

当符合一条或多条以下条件时,请考虑构建结构体:

  • 结构体的主要目的是用来封装少量相关的简单数据值
  • 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用
  • 任何在结构体中储存的值类型属性,也会被拷贝,而不是被引用
  • 结构体不需要去继承另一个已存在类型的属性或者行为

为什么Swift中推荐使用Struct?

Swift 里更推荐使用值类型变量(struct)而不是引用类型(class)的变量,Swift中许多常见的数据类型,字符串,集合类型以及结构体和枚举都是值类型而非引用类型,值类型的变量在赋值时会自动进行一次低消耗的值拷贝,对比对象的copy要更加高效而且不存在线程安全的问题.

 

上面就是Swift中的Struct结构体.希望对大家有所帮助!!!

 

posted @ 2019-10-17 16:11  国孩  阅读(834)  评论(0编辑  收藏  举报