IOS中之struct(结构体)
前言
-
引用类型: 赋值时,系统不会对其对象拷贝,而是把指向该对象的指针(对象的地址值)赋值给另外一个对象,当修改某个对象的值,会随之影响另外一个对象的值
-
值类型: 赋值时,系统会对此对象进行拷贝,赋值出一份副本给另外一个对象,当修改一个对象的值时不影响另外一个对象
在Swift中struct是属于值类型,相对于其他语言来说,Swift的结构体功能更加强大,它除了支持在结构体声明中基础变量之外,它还支持在结构体中声明方法,这相对于其他语言来说,是swift的一个特性之一。
swift在本质上来说是面向协议(Protocol Oriented)的语言,struct没有也不需要继承的功能,为了实现某个功能,struct去服从并实现某个协议就即可,从一个较高的层次来看,struct+protocol是构成swift面向协议语言的两个基石
- 为什么需要使用结构体
- struct可保证代码更加安全可靠,以及struct+protocol更加切合swift面向协议编程的初衷。
- struct 更快,简单,安全,适合数据处理操作使用,在iOS开发中适合http请求的数据操作中使用。对于数据的处理解析和其他操作更快,更省内存。
struct的基本语法
- 结构中声明变量,可以不用初始化值,但是calss中需要初始化值的
- Struct 会自动生成一个初始化成员变量的构造器方法,创建结构体的时候调用构造器方法赋值,但是class需要自己生成
struct StructTest {
var name: String
var age: Int
var color: UIColor
}
let test = StructTest(name: "guoweiyong", age: 23, color: UIColor.red)
- 如果你重写了init()方法,系统不会帮你生成初始化构造器方法了。
init(name: String, age: Int) {
self.name = name
self.age = age
self.color = UIColor.red
}
let test2 = StructTest(name: "GY", age: 22)**加粗样式**
struct
中声明方法,如果方法内部修改了struct
中声明property
(属性)值,方法前面必须加上mutating
关键字,如果没有涉及到修改属性值的话,就不需要mutating
修饰,正常声明实现方法即可
//日过定义的方法中需要修改属性值 必须要加上关键字mutating修饰方法
mutating func funcTest(_ tempName: String) -> Void {
self.name = tempName
}
func funcTest2() -> String {
return name;
}
struct调用方法和类一样,对象.方法名()
- 如果struct中声明属性时,有一些属性有初始化值,有一些没有,那么系统会自动生成两种成员变量构造器方法,一种是包括所有的成员变量,一种是只含有没有初始化值的成员变量构造器方法
struct StructTest {
var name: String
var age: Int = 23
var color: UIColor
}
//这两种初始化方法都是正确的
let test3 = StructTest(name: <#T##String#>, age: <#T##Int#>, color: <#T##UIColor#>)
let test4 = StructTest(name: <#T##String#>, color: <#T##UIColor#>)
struct对于let声明的实例不能对变量进行赋值,class预设值是可以赋值let实例的。注意Swift中常用的String、Array、 Dictionary都是struct。
struct 和class的区别
主要区别:
-
struct是值引用,而class是类型引用(各有好处值类型不用担心内存问题,但无法跨view完成同一个对象调用,只能是copy一份新对象使用。class 的内存问题是需要程序要注意的,但是指针引用的强大毋庸置疑的。值类型是在栈空间上操作的,引用类型是在堆控件操作的)
-
struct没有继承的功能,class有继承功能(struct不能像class 一样继承完成重用和多态。但是struct 可以通过组合和接口实现完成重用和多态。从这一点来说struct是比class有优势的)
-
定义结构体
struct
类型时其成员变量可以没有初始值(编译器会自动生成一个成员构造器,给变量赋一个默认值),如果使用这种格式定义一个类,编译器会报错,他会提醒你这个类没有被初始化
struct SRectangle {
var width = 200
var height: Int
}
class CRectangle {
var width = 200
var height: Int // 报错
}
class和struct比较,优缺点?
class有一下功能,struct是没有的:
- 1.class可以继承,子类可以使用父类的特性和方法。但是struct是不能被继承的
- 2.类型转换可以在运行时检查和解释一个实例对象
- 3.class可用 deinit来释放资源
- 4.一个类可以被多次引用
struct的优势
- 结构较小,适用于赋值操作,相比较一个class, 实例被多次引用(容易发生内存泄漏),struct更安全
- 无需担心内存泄漏问题(struct的操作都是在栈控件上,class在堆控件上)
使用Struct和Protocol来实现model的继承和共享
- 在项目中如何选择
Struct
和Class
- 默认使用
Struct
- 当你需要继承Objective-C某些类的的时候使用class
- 当你需要控制唯一性时使用class
- 我们使用struct和protocol来实现model继承和共享行为
- 默认使用
protocol AnimalCommonProtocol {
var name: String? {get set} //表示属性是可读写的,{ get }用来表示属性为可读的
var weight: Double {get set}
func run()
}
struct Cat: AnimalCommonProtocol {
func run() {
print("cat run")
}
var name: String?
var weight: Double
/// 自增属性
var gender: String?
}
struct Dog : AnimalCommonProtocol {
var name: String?
var weight: Double
/// 自增属性
var type: String?
func run() {
print("Dog run")
}
}