写在前面
因为之前有过Swift开发的些许经验,但是其实根本没有好好了解Swift和Obj-C的基本原理和常用框架,这次秋招感觉没戏,所以好好做完手头的事,努努力啃完Swift Obj-C 还有常用八股文争取春招拿到好offer加油加油。简单的很容易记住的就不写啦,这里记一些我比较模糊的模块。
Swift基础模块
输出参数
print函数有两个参数seperator和terminator separator 和 terminator 形式参数有默认值,所以可以在调用这个函数的时候忽略它们。默认来说,函数通过在行末尾添加换行符来结束输出。要想输出不带换行符的值,那就传一个空的换行符作为结束——比如说, print(someValue, terminator: “”) 。
注释
Swift中允许内嵌注释,注释可以在任意地方,不会影响编译
整数
Swift中有UInt和Int两种形式,其中32位电脑默认为Int32,Swift提供8,16,32,64位的整型数。
浮点数
Double64位 Float32位
类型安全和类型推断
浮点数默认为Double
数值型字面量
前缀:2进制 0b 8进制 0o 16进制 0x
为了增减代码的可读性,可以在数值中添加下划线,不影响程序编译,如1_000_000
整数转换
当整数存在越界问题的时候,可以先定义一个更大的整数类型后,用该类型的初始化器进行初始化后储存该值。但只能传入该类型
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
类型别名
可以用typelias为类型定义别名。
元组使用方法
1.分解成单独的常量或变量
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// prints "The status code is 404"
print("The status message is \(statusMessage)")
// prints "The status message is Not Found"
2.只使用一部分数据,别的数据用下划线代替
let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
3.从0开始的索引访问元素
print("The status code is \(http404Error.0)")
// prints "The status code is 404"
print("The status message is \(http404Error.1)")
// prints "The status message is Not Found"
4.为元组的元素命名后使用对应的命名获取元素的值
let http200Status = (statusCode: 200, description: "OK")
print("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
print("The status message is \(http200Status.description)")
// prints "The status message is OK"
可选项绑定
可以用if和while语句来判定一个可选项是否包含值
if let constantName = someOptional {
statements
}
也可用于判断类型是否转化成功
if let actualNumber = Int(possibleNumber) {
print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
print("\'\(possibleNumber)\' could not be converted to an integer")
}
也可以通过与运算确保每一个都包含值。
隐式展开可选项
若在赋值的时候不显式写明类型则会隐式展开可选项后进行类型的复制:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark
let optionalString = assumedString
// The type of optionalString is "String?" and assumedString isn't force-unwrapped.
同时可以对隐式展开可选项进行绑定以检查和展开值
断言
断言和错误处理不同,断言出现说明程序处于非法状态因此需要终止
断言全局函数
assert( _ : _: )第一个参数为先决条件,第二个参数为错误信息
也可以使用assertionFailure( _ ,file:,line:)来表明断言失败(首个参数为报错信息)
强制先决
可以使用 precondition( _ :,file:,line:) 来写先决条件,也可以使用preconditionFailure( _ :, file:, line:)来标明错误发生了,比如在switch中,所有其他合法数据都应该被处理时。
注意: 不在检查编译模式 -Ounchecked中先决条件不会被检查,但是用 fatalError( _ :, file:, line:) 时函数一定会终止运行,所以函数可以使用fatalError标记那些还没实现的功能。系统遇到这个占位符一定会终止
基本运算符
赋值
和OC不同,赋值的时候不会返回值,所以作为判断条件是非法的
三元条件运算符
和C++用法一样 ? :
合并空值运算符
”??“
前面的一定要是可选值,否则直接短路运算,一般用于判断是否有值,没有的话就使用默认值
(算法里面,对字典没有的选项就可以使用 if array[index] ?? -1 != -1, 当然好像直接用 array[index] != nil 也一样,当我没说)
区间运算符
闭区间和半开区间用很多就不记录了
单侧区间
闭区间有另外一种形式来让区间朝一个方向尽可能的远——比如说,一个包含数组所有元素的区间,从索引 2 到数组的结束。在这种情况下,你可以省略区间运算符一侧的值。因为运算符只有一侧有值,所以这种区间叫做单侧区间。比如说:
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[2...] {
print(name)
}
// Brian
// Jack
混合逻辑运算
&&和||都是做相关的,也就是说都会先判断左边,如果没必要判断右边就不会运行对应表达式。
当然最好使用显式括号增加可读性。
字符串和字符
写在前面
Swift 的 String类型桥接到了基础库中的 NSString类。Foundation 同时也扩展了所有 NSString 定义的方法给 String 。
也就是说,如果你导入 Foundation ,就可以在 String 中访问所有的 NSString 方法,无需转换格式。
(现在还没有学习oc,到时候再回来看看)
多行字符串
用""“开始用”""结束
换行作为换行符占1个位置,可以增加 \ 增加可读性
若要开始或者结束换行就空一行
同时,如果要计算空格,就要放在结束的三个双引号那一列的后面,否则会忽略掉对应的空格
字符串字面量里的特殊字符
任意的 Unicode 标量,写作 \u{n},里边的 n是一个 1-8 个与合法 Unicode 码位相等的16进制数字。
扩展字符串分隔符
通过把字符串放在双引号( " )内并由井号( # )包裹。可以让他们的转义不生效。比如说,打印字符串字面量 #“Line 1\nLine 2”# 会打印出换行符 \n 而不是打印出两行。
初始化一个空字符串
可以通过检查isEmpty属性来判断这个字符串是不是空的
字符串是值类型
Swift 的 String类型是一种值类型。如果你创建了一个新的 String值, String值在传递给方法或者函数的时候会被复制过去,还有赋值给常量或者变量的时候也是一样。每一次赋值和传递,现存的 String值都会被复制一次,传递走的是拷贝而不是原本。
操作字符
可以通过 for-in循环遍历 String 中的每一个独立的 Character 值:
for character in s{}
String值可以通过传入 Character值的字符串作为实际参数到它的初始化器来构造:
连接字符串和字符
String类的值对象可以直接用+进行连接
在String值对象中添加字符使用append()函数
Unicode标量
Unicode 标量码位位于 U+0000到 U+D7FF或者 U+E000到 U+10FFFF之间。Unicode 标量码位不包括从 U+D800到 U+DFFF的16位码元码位。
扩展字形集群
有些 Unicode 可能通过组合化为一个字符
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ́
// eAcute is é, combinedEAcute is é
同样比较经典的例子还有韩文,这样他们就会变成一个character。 在判断是否String 值是否相等的时候,他们是一样的。
同时在 String 的count中,他们也仅作为1个计数,这也导致了它和NSString中的length长度不会一直相等,NSString中的长度是基于在字符串的 UTF-16 表示中16位码元的数量来表示的,而不是字符串中 Unicode 扩展字形集群的数量。
注意: String在获取自己的count的时候需要遍历整个值。
访问和修改字符串
每一个 String值都有相关的索引类型, String.Index,它相当于每个 Character在字符串中的位置。
开始的索引为startIndex,结束的索引为endIndex,endIndex不是一个合法的下标值,他是最后一个字符后面的索引
由于扩展字形的存在,每个字符分配的内存不一样所以不能用整数去作为索引
常用的index的函数:
index(after:)
index(before:)
index(_:, offsetBy:)
index(of:) ---- 第一个
可以用**.indices**来访问字符串中每个字符的索引
遵循Indexable协议的类型都可以使用这些方式,如Array,Set,Dictionary。
插入和删除
字符:
insert( _ :,at:)
remove(at:)
字符串
insert(contentsOf:,at:)
removeSubrange(_ : ) --参数为indices的范围
这些方法可以再遵循RangeReplacableIndexable协议的类型中使用,像上面说的。
子字符串
如果获取了一个字符串的子字符串,相当于是重用了字符串的内存,这个机制原本是为了在修改该字符串之前都不用花费拷贝内存的代价。但是这也使得子字符串不方便长时间存储,因此最好重新定义一个有独自内存的变量进行赋值。
String 和 Substring 都遵循 StringProtocol 协议。可以无差别的使用其中的函数。
字符串和字符相等性
两个 String值(或者两个 Character值)如果它们的扩展字形集群是规范化相等,则被认为是相等的。
前缀和后缀相等性
hasPrefix( : ) hasSuffix( : )
如同字符串和字符相等性一节所描述的那样, hasPrefix(:)和 hasSuffix(:)方法只对字符串当中的每一个扩展字形集群之间进行了一个逐字符的规范化相等比较。
字符串的 Unicode 表示法
可以通过遍历 utf8 属性来访问一个 String的 UTF-8 表示法。这个属性的类型是 String.UTF8View , 返回的是UInt8的值
同理 String.UTF16View,返回的是UInt16的值
String.UnicodeScalarView(21位Unicode码),返回的是UInt32的值。
集合类型
数组,集合,字典
总是能明确他们储存的值的类型 且都是以泛型集合实现的
集合的可变性
如果不赋值给常量集合都是可变的
数组
以有序的类型储存相同的值。
Swift中的Array类型被桥接到了基础框架的NSArray上
数组简写语法
[Int]
创建空数组
使用默认值创建数组
var temp = [Int](repeating: 3, count: 12)
连接两个数组
用+
使用字面量创造数组
访问和修改数组
常用属性:isEmpty, count
常用方法:
insert(_ : ,at:)
remove(at:)
removeFirst()
removeLast()
append()
可以进行范围赋值,赋值的数量不一定要相等
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items
合集
Set类型的哈希值
Set类型桥街到基础框架的NSSet类上
为了让值能够存在集合中,他的类型一定是需要可哈希的,也就是说类型必须提供计算它自身哈希值的方法,也就是需要遵循Hashable协议所有Swift的基本类型都是默认可哈希的
访问和修改合集
常用属性 count , isEmpty。
常用方法:
insert( _ : )
remove ( _ : ) -> 返回
removeAll()
contains( _ : )
遍历合集
可以用for-in遍历合集
如果要有序遍历可以用成员函数 .sorted()
基本合集操作
.union( _ : )
.intersection( _ : )
.subtracting( _ : )
.symmetricDifference( _ : )
集合成员关系和相等性
.isSubset(of: )
.isSuperset(of: )
.isStrictSubset(of: )
.isStrictSuperset(of: )
.isDisjoint(with: )
字典
桥接到基础框架的NSDictionary类
其中键一定要符合Hashable协议
访问和修改字典
updateValue( _ :, forKey: )返回一个值类型的可选值,如果原本该键有对应的值则返回被删除的值
当给一个键的字典赋值为nil相当于删除该键值对
removeValue(forKey: )同样返回值类型的可选项
遍历字典
可以用for-in对字典进行遍历
可以直接对字典的keys属性和values进行遍历
也可以用一个Array实例,然后用keys或者values来初始化。