文章目录
1. 结构体和类
1.1 成员方法对成员属性的修改
以上会出现报错,是因为 struct 属于值类型,默认情况下,它的属性不可以被成员方法修改。
但是以下两种解决方案可以实现修改:
- 方法一: @State 修饰成员变量
struct ContentView: View {
@State private var myValue = 10
var body: some View {
Text("Hello, World!")
}
func canIChangeTheValue(){
self.myValue = 20
}
}
- 方法二:使用 修饰成员方法
struct ContentView: View {
private var myValue = 10
var body: some View {
Text("Hello, World!")
}
mutating func canIChangeTheValue(){
self.myValue = 20
}
}
在 class类中,成员方法默认是可以修改成员变量的。
1.2 值拷贝与引用拷贝
struct 类型直接的直接 “=” 赋值,其实是对值进行了一份拷贝,实际的两个值是两个独立的值
struct Resolution {
var width = 0
var height = 0
}
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
print("cinema is now \(cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"
print("hd is still \(hd.width) pixels wide")
// Prints "hd is still 1920 pixels wide"
class 类之间的 “=” 赋值,是引用赋值,其实是将一个对数据单元的引用地址赋值给另一个类。
注.class 类中的成员变量必须要有初始值或者可选变量
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
附:在Java语言中也是同样的道理,根据输出的对象的引用地址相同可以看出,使用"="的赋值,只是拷贝了引用地址。
2. @State 和 @ObservedObject
2.1 使用@State修饰结构体属性
@State 是对结构体属性的修饰,当结构体 View 中定义的属性被 @State 修饰后,我们就可以在视图上实时监测到这个属性值的变化 并且对视图刷新。
struct User{
var firstName = "Bilbo"
var lastName = "Baggins"
}
struct ContentView: View {
@State private var user = User()
var body: some View {
VStack{
Text("Your name is: \(user.firstName) \(user.lastName)")
TextField("First name", text: $user.firstName)
TextField("Last name", text: $user.lastName)
}
}
}
上面代码执行后可以看到在文本框中无论是修改“Firstname”还是“Lastname"那么在Text中都会发生改变。这时因为每当对结构体User的属性改变都相当于重新复制了-份儿结构体的实例,也就是说不管是修改了user.firstName还是user.lastName,这个user就不再是之前的user了,而是一个新的user。而user的改变也就直接导致ContentView的属性改变,所以ContentView也被重新实例化了,于是我们会看到整个视图的内容也发生了变化。其实我们看到的这个变化的视图已经不再是之前的那个视图了。
如果我们把上述代码的第1行的关键字struct修改为class 后:
class User{
var firstName = "Bilbo"
var lastName = "Baggins"
}
struct ContentView: View {
@State private var user = User()
var body: some View {
VStack{