编辑代码

记了不看,也就失去了记笔记的意义。
要时刻清楚自己的目的,是掌握知识,而记笔记只是手段和方法,不要本末倒置。

将看笔记作为每日必办,每天安排固定的时间,少则十分钟,多则半小时,
用来温习旧的笔记。 将这件事养成习惯,也就能坚持下去了。 长久坚持,必然获益良多。

一道好菜,要色香味俱佳,才能吸引食客的目光。
一本笔记,也要排版漂亮、内容精致,才能让自己有回顾的冲动。

esc代码提示
选中 + control + I 规范格式
⌘ + ◀︎ ► ▲ ▼ 光标移到行首、 行末、 文首、 文末

Xcode中press Shift+Cmd+O to bring up the Open Quickly menu, 
make sure the Swift icon on the right is colored in rather than hollow, 
(注: the Swift icon 可点击切换)来到了真正的源代码
then type 你想查找的.继续按 Cmd + F 搜索更细致的内容。

option + 关键字  跳出一个关于定义的弹窗,可能比上面这个更抽象和快捷

安装了软件snipaste,按fn+F1即可截屏,随后可以置顶在屏幕。随后我又设置了,按住option键+双击,关闭截屏。

问:看得懂写不出来怎么办?
答:
(1)我需要输入什么?
(2)我需要输出什么?
(3)我需要几个步骤来处理?如果只有一步,就写出来;如果有多步,那么把每一步拆分出来,再回过去问自己第(1)-(2)题,直到所有步骤都弄完。

command emitswiftmodule failed with a nonzero exit code
当Xcode编译运行多次,可能会出现此报错,Command+Shift+K,clean一下,再重新运行
或者在Product下拉菜单中选择Clean Build Folder

shift + command + C 或者 View - Debug Area - Activate Console, 显示控制台。

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour
Swift官英本

https://gitbook.swiftgg.team/swift/swift-jiao-cheng/01_the_basics
Swift官中本

不做天才app,只做普通app。哪怕代码冗杂和低效。
海量文献和视频,一辈子都看不完,只看相关的。

2024.7.6突然想,也许可以用读书时的方法来学习编程。如死记硬背概念,然后才是理解概念,做做每章的练习题,没有练习题就仿写代码,不断的滚基础文档,做到每个标记都了然于胸。
1,读懂swift程序代码
3,寻找、筛选、甄别 比较耗时间,占据了一天的大部分时间。
4,所以英语好也是一个优势,不用看别人的解读,不用看过时文章、直接阅读中心原文,快速省事。
5,降低学习成本这件事是非常有意义的。
6,遇见知识点,最好去Xcode中验证,否则学了半天,才发现是过时的内容
7,数组的完整写法为 Array<Element>,但是推荐使用像 [Element] 这样的简单语法。
8,集合类型被写为 Set<Element>,和数组不同的是,集合没有等价的简化形式。 以数组字面量的形式创建集合。
9,推荐用 [Key: Value] 这样简化的形式去表示字典类型。 以类似数组的形式创建字典。
可通过访问 keys 或者 values 属性,单独遍历字典的键或者值
2,冒号后面必须空一格

print里面是不定参数,可以直接print(a,b,c)。a,b,c可以是整形布尔等,直接放不用双引号,但是只有两个字符串之间可以用+号拼接语句,其他的组合要转换。
\()要用在双引号内

switch是所属匹配,不是==匹配。比如"b"可以匹配case  "a","b","c":
循环跳着取值,用for index in stride(){
反向取值,用.reversed()

6,如果你要处理的值不需要改变,那使用常量可以让你的代码更加安全并且更清晰地表达你的意图。评:已经习惯必须要有清晰定义的这种习惯。
7,可选类型比 Objective-C 中的nil指针更加安全也更具表现力,它是 Swift 许多强大特性的重要组成部分。(Swift 是一门类型安全的语言,可选类型就是一个很好的例子。)
SwiftString类型有一个叫做toInt的方法,作用是将一个String值转换成一个Int值。然而,并不是所有的字符串都可以转换成一个整数。
字符串"123"可以被转换成数字123,但是字符串"hello, world"不行。
这个例子很好解释了为什么需要可选类型。

10,空合运算(a ?? b)是对a != nil ? a! : b的简短表达。

在实际问题中有时候我们需要几种数据类型一起来修饰某个东西。 例如一个学生的信息就需要学号(字符串),姓名(字符串),年龄(整型)等等。
这些数据类型都不同但是他们又是表示一个整体。

15,在 Swift 中,你可以在循环体和条件语句中嵌套循环体和条件语句来创造复杂的控制流结构。
并且,循环体和条件语句都可以使用 break 语句来提前结束整个代码块。因此,显式地指明 break 语句想要终止的是哪个循环体或者条件语句,会很有用。

26、泛型的类型检查由编译器负责,而 Any 修饰则避开了类型系统。
综合比较而言,应该尽量多使用泛型,少使用 Any ,尽量避免转换类型时发生的类型错误。

30、表达式(1 + 2) * 3 - 4,写成函数式语言:
subtract(multiply(add(1,2), 3), 4)
对它进行变形,不难得到另一种写法:
add(1,2).multiply(3).subtract(4)
因此,函数式编程的代码更接近自然语言,易于理解。

32let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // 输出 15
猜测reduceArray的一个方法,于是查阅Xcode的开发文档,原来0是第一个参数的默认值(当Array为空时返回它),闭包是函数的第二个参数,因为它是最后一个参数,所以写成了跟随闭包的形式。

20231224日总结
1,某天偶然看到某个博主的视频中出现过一小段和目标相近的动画,惊奇的同时觉得这个动作也许有用,记录下来准备有时间在这个动作上找找灵感,
然后昨天翻出来,发现屏幕上竟然有代码,于是一个个的敲下来,试了几下并没有运行成功。
2,今天一早又拿出来研究,用自己的经验常识进行修改,终不得行。在百度然后一行一行把代码敲进body比对的时候,发现} .gesture(的gesture应该跨行,
它不是mask的属性,而是整个矩形的属性,然后运行,竟然成功了。
3,然后想为什么原来包装在一个方法中然后调用的办法为什么不行呢,于是把body中的代码和方法中的代码进行比对修改,不管是调格式、增删空格、
用print打印(最后发现打印台并未开启)等等办法都不得行,圆是显示的,但是gesture内的代码始终不运行,无奈回到body想重温一下成功的代码,结果也不运行。
4,同一段代码,过了一会竟然不运行,我猜应该是MacBook的问题或者是Xcode的问题了,于是连接手机来调试,手机上一切正常,用方法调用的方法也正常!

Confidence is the feeling you have before you really understand the problem.

枚举用于表示一组固定的相关值或状态。 通常用于状态机或配置选项等场景。
何时使用枚举?
状态管理: 当需要管理不同状态时,比如网络请求的状态(加载中、成功、失败)。
配置选项: 例如,UI 组件的不同状态(如按钮的不同状态:正常、高亮、禁用等)。
动作处理: 处理接收的一组操作,比如用户输入的指令或事件。
与数据模型结合: 如 API 响应的不同状态(成功、错误、无数据等)。
小结
虽然结构体和数组在某些方面也可以实现类似功能,但枚举的类型安全、相关值和模式匹配能力使其在特定场景中更为合适。 
枚举能够帮助组织代码、提高可读性及维护性,是 Swift 编程中的一个重要工具。
理解和应用枚举能够让你的代码更加清晰、稳健。
使用 switch 语句处理枚举类型时,语法简洁明了,代码可读性高。
enum TrafficLight {
    case red, yellow, green
}
func trafficLightAction(light: TrafficLight) {
    switch light {
    case .red:
        print("Stop")
    case .yellow:
        print("Caution")
    case .green:
        print("Go")
    }
}
trafficLightAction(light: .red) 

计算属性可以很方便地为你的类、结构体和枚举提供动态的属性值。
具体运用场景:一、动态计算:
当你需要根据其他属性的值进行动态计算时,可以使用计算属性。
struct Rectangle {
    var width: Double
    var height: Double
    
    var area: Double {
        return width * height
    }
    
    var perimeter: Double {
        return 2 * (width + height)
    }
}
let rect = Rectangle(width: 5, height: 10)
print(rect.area)       // 输出: 50
print(rect.perimeter)  // 输出: 30
二、封装逻辑:
计算属性可以用来封装一些常用的逻辑,从而提供简洁的接口。例如,一个用户模型,可以通过计算属性来检查用户是否成年。
struct User {
    var age: Int
    
    var isAdult: Bool {
        return age >= 18
    }
}
let user = User(age: 20)
print(user.isAdult)  // 输出: true
优势:
一、 易于维护:计算属性可以提高代码的可读性和可维护性,因为它们提供了更清晰的接口,可以在计算属性里隐藏复杂的逻辑。
二、 无副作用:计算属性是根据其他属性的值动态计算的,不会储存值。 如果基础属性变化,计算属性会自动更新。
三、 封装与抽象:使用计算属性可以隐藏复杂的算法或逻辑细节,从而提供简单的、高层的抽象。
四、 避免冗余:使用计算属性避免了与直接存储属性重复数据的问题,确保数据的一致性。
不得不用的地方:(其实还有一条: 如果存储属性还没有初始化,直接使用会导致编译器报错)
避免存储属性:在需要动态计算的情况下,不使用计算属性而选择存储属性,会导致重复数据存储并可能引起数据不同步的问题。
struct Rectangle {
    var width: Double
    var height: Double
    var area: Double  // 存储属性,意图存储面积

    mutating func updateDimensions(newWidth: Double, newHeight: Double) {
        width = newWidth
        height = newHeight
        area = newWidth * newHeight  // 这里手动更新面积
    }
}

var rect = Rectangle(width: 5, height: 10, area: 50)
rect.updateDimensions(newWidth: 8, newHeight: 4)
print(rect.area)  //相当于进行了两次不同的赋值,会导致数据与意向不一致,输出错误的(意外的)结果。
总结
计算属性是 Swift 中一个非常强大的特性,可以帮助开发者简化代码,提高可读性和可维护性。
它们特别适合在需要动态计算、封装逻辑或避免数据冗余时使用。 理解如何有效运用计算属性可以帮助你设计出更清晰和高效的代码结构。

一些在特定情况下闭包是必不可少的情形:
1.闭包最常见的用法之一是在异步操作中作为回调。
2.当使用高阶函数(如 mapfilterreduce)时,闭包是必不可少的,因为它们需要一个函数作为参数来定义如何处理集合中的每个元素。
3.闭包可以用于延迟执行某些代码块,这在懒加载或后续使用时非常有用。
一些提高对 Swift 闭包理解和可读性的方法:
一、 命名闭包可以提高代码可读性。通过为闭包定义类型,能够清晰表达闭包的目的和功能。
typealias CompletionHandler = (Data?, Error?) -> Void
func fetchData(completion: @escaping CompletionHandler) {
    // 实施异步操作
}
二、 多练习如排序、过滤、映射等常见操作,熟悉它们各自的闭包用法。掌握这些基础之后,扩展到更复杂的逻辑。

协议在 Swift 中扮演着非常重要的角色,它们使得代码更加灵活、可重用和可维护。
协议是一种蓝图,它定义了一组方法、属性和其他要求,供遵循该协议的类型实现。协议本身并不提供实现,而是规定了必须实现的结构。
以下是一些必须使用协议的情形:
1.提供一致的接口: 当你需要定义一组具有相似功能的类、结构或枚举,但这些类型在内部实现上可能有所区别时,可以使用协议。
2.多重继承的替代: Swift 不支持多重继承,但通过协议可以实现协作和共享某些功能。类型可以遵循多个协议,从而组合不同的行为。
使用协议可以带来以下便利:
代码重用性: 协议提供了一种机制,允许不同类型通过协议方式实现相同的功能,减少代码重复。
解耦设计: 通过协议进行设计时,具体实现与使用方之间的依赖关系较弱,使得代码更加灵活,易于扩展和维护。
增强可读性: 使用协议可以使代码结构更加清晰明了,便于开发人员理解各部分的职责。
组合行为的例子:
我们定义了两个协议 AnimalPet,前者包含动物的基本行为(如名称和叫声),后者包含宠物的行为(如玩耍)。
Dog 类型通过遵循两个协议,能够同时具备动物的基本行为(如发出声音)和宠物的特定行为(如玩耍)。
这意味着 Dog 类型的实例可以在需要 Animal 行为的上下文中使用,也可以在需要 Pet 行为的上下文中使用。
总结:我们可以根据不同的需求自由组合,实现全面的功能,而不必依赖于单一的继承层次结构。
这种设计使得在应用程序开发中,可以更好地管理和组织代码。
明确的协议能够在编译时检查实现是否符合要求。如果通过默认实现,这种检查是无法进行的。协议提供的结构可以减少错误,提高代码的可维护性。
增强可读性和可理解性:通过清晰的协议定义,开发者未来查看代码时能够迅速理解不同组件之间的关系和期望的行为。
灵活性:当需要引入新功能或修改现有功能时,协议能够提供更好的灵活性。只需创建新的遵循协议的类型,而不必改动已有代码。

编程中“继承”的中心思想是什么?
答:代码重用:继承允许子类重用父类(基类)中已经定义的属性和方法。通过继承,开发者可以避免重复编写相同的代码,提升开发效率。
扩展性:继承使得在已有类的基础上创建新类变得容易。子类可以在继承父类的基础上增加新功能或重写父类的方法,从而扩展其功能。
这种灵活性便于后续修改和功能扩展。