簡單記錄一些自己容易忘記的碎片化的點
一炭庙、tips
1、swift中文名雨燕
2轧苫、不用編寫main函數(shù),將全局范圍內(nèi)首句可執(zhí)行代碼作為程序入口
3疫蔓、一句代碼尾部可以省略分號浸剩,多句代碼寫到同一行必須用分號隔開
4、var定義變量鳄袍,let定義常量,編譯器能夠自動推斷出變量和常量的類型
二吏恭、常見數(shù)據(jù)類型
三拗小、函數(shù)文檔注釋
///
/// 求和【概述】
///
/// 將兩個整數(shù)相加【更加詳細的描述】
///
/// - Parameter a: 參數(shù)a描述
/// - Parameter b: 參數(shù)b描述
/// - Returns :兩個整數(shù)的和
///
/// - Note:傳入兩個整數(shù)即可【批注】
///
func sum(a: Int, b: Int) -> Int {
a + b
}
調(diào)用的時候,按住option樱哼,點擊函數(shù)名即可出現(xiàn)下圖的注釋效果:
MARK / TODO / FIXME
- MARK: 類似于OC中的 #pragma mark
- MARK: - 類似于OC中的 #pragma mark - (預(yù)覽的時候跟上個相同級別的標(biāo)注之間會有線隔開哀九,見下面圖片中灰色線條)
- TODO: 用于標(biāo)記未完成的任務(wù)
- FIXME: 用于標(biāo)記待修復(fù)的問題
-
warning("undo"):如果覺得 TODO: 不夠明顯, 可以考慮用這個
// MARK: - 私有方法
// MARK: test1方法
private func test1() {
// TODO: 未完成
}
// MARK: test2方法
private func test2() {
// FIXME: 有待修復(fù)的問題
}
// MARK: - 公共方法
// MARK: test3方法
public func test3() {}
// MARK: test4方法
public func test4() {}
// 警告搅幅,會在代碼中有明顯的黃色嘆號提示
#warning("undo")
四阅束、參數(shù)
1、可以修改參數(shù)標(biāo)簽
func gotoSchool(at time: String) {
print("go to school \(time)")
}
gotoSchool(at: "08:00")
2茄唐、可以使用下劃線_ 省略參數(shù)標(biāo)簽息裸,相對復(fù)雜的盡量不要省略
func sum(_ a: Int, _ b: Int) -> Int {
a + b
}
print(sum(10, 20))
3、參數(shù)類型后面加上三個點表示可變參數(shù)沪编,可以傳多個對應(yīng)類型的參數(shù)
需要注意的問題:
1呼盆、一個函數(shù)最多只能有一個可變參數(shù)
2、緊跟在可變參數(shù)后面的參數(shù)不能省略參數(shù)標(biāo)簽
func sum(_ numbers: Int...) -> Int {
var total = 0
for number in numbers {
total += number
}
return total
}
print(sum(10, 20, 30, 40)) // 100
五蚁廓、Optional-可選項
可選項访圃,一般也叫可選類型,它允許將值設(shè)置為nil相嵌,在類型名稱后面加個腿时?來定義一個可選項
var name: String? = "Jack"http:// 不寫= "Jack",默認(rèn)就是nil
name = nil
可選項是對其它類型的一層包裝饭宾,如果要從可選項中取出被包裝的數(shù)據(jù)批糟,需要使用感嘆號!進行強制解包
let count: Int? = 10
var countAdd: Int = count!
countAdd += 10
print(countAdd)
如果對值為nil的可選項進行強制解包捏雌,會產(chǎn)生運行時錯誤跃赚,程序直接崩潰
let count: Int?
// 如果count為nil,強制解包程序會crash
count!
// 在實際開發(fā)中我們一般會這樣做
if let temp = count {
// 在這里進行處理
print(temp)
}
可選項的本質(zhì)是 enum 類型,下面兩種寫法完全等價
let a: Int? = 10
let b: Optional<Int> = .some(10)
六纬傲、運算符
1满败、??:合并空值運算符
a ?? b
(1)用于判斷常量或者變量的值是否為nil,如果為nil叹括,則取后面的值算墨,不為nil,取前面的值汁雷。有點兒類似三目運算符
(2)上面的表達式净嘀,如果a有值,則取a侠讯,如果a為nil挖藏,則取b
應(yīng)用示例:
func sum(a: Int?, b: Int?) -> Int {
// 方法一:如果a或者b有nil,則程序會crash
return a! + b!
//方法二:判斷條件太多厢漩,容易遺漏
if a != nil {
if b != nil {
return a! + b!
} else {
return a!
}
} else {
if b != nil {
return b!
} else {
return 0
}
}
//方法三:簡潔膜眠、安全
return (a ?? 0) + (b ?? 0)
}
2、reversed():倒序索引
for i in (0...9).reversed() {
print(i)
}
// 輸出結(jié)果
9
8
7
6
5
4
3
2
1
0
3溜嗜、 (逗號)
做判斷的時候在兩個條件中間加一個 相當(dāng)于 &&
let a: Int = 11
// 判斷1 和 判斷2 等價
// 判斷1
if a > 0, a > 11 {
print(123)
}
// 判斷2
if a > 0 && a > 11 {
print(123)
}
七宵膨、guard
guard語句,有點兒類似if語句炸宵,但是后面會一直跟著else語句辟躏,并且else里面的語句只有在guard條件不為真的時候才執(zhí)行。下面兩段代碼是檢測ip地址是否正確土全,第一段用if實現(xiàn)捎琐,第二段用guard實現(xiàn)。
// 試用if判斷ip地址是否正確
func checkIpAddress(ipAddress: String) -> (Int, String) {
// 用點來分割ip地址
let compoment = ipAddress.split(separator: ".")
if compoment.count == 4 {
if let first = Int(compoment[0]), first >= 0 && first < 256 {
if let second = Int(compoment[1]), second >= 0 && second < 256 {
if let third = Int(compoment[2]), third >= 0 && third < 256 {
if let fourth = Int(compoment[3]), fourth >= 0 && fourth < 256 {
return (100, "ip地址是正確的")
} else {
return (4, "ip地址第四部分不對")
}
} else {
return (3, "ip地址第三部分不對")
}
} else {
return (2, "ip地址第二部分不對")
}
} else {
return (1, "ip地址第一部分不對")
}
} else {
return (0, "ip地址必須有四部分")
}
}
// 試用guard判斷ip地址是否正確
func checkIpAddress(ipAddress: String) -> (Int, String) {
let compoment = ipAddress.split(separator: ".")
guard compoment.count == 4 else {
return (0, "ip地址必須有四部分")
}
guard let first = Int(compoment[0]), first >= 0 && first < 256 else {
return (1, "ip地址第一部分不對")
}
guard let second = Int(compoment[1]), second >= 0 && second < 256 else {
return (2, "ip地址第二部分不對")
}
guard let third = Int(compoment[2]), third >= 0 && third < 256 else {
return (3, "ip地址第三部分不對")
}
guard let fourth = Int(compoment[3]), fourth >= 0 && fourth < 256 else {
return (4, "ip地址第四部分不對")
}
return (100, "ip地址是正確的")
}
八涯曲、字符串
1野哭、首字母大寫:capitalized
let str = "hello world"
print(str.capitalized)
// 輸出:Hello World
2、字符全部轉(zhuǎn)大寫
let str = "hello world"
print(str.uppercased())
// 輸出:HELLO WORLD
3幻件、字符全部轉(zhuǎn)小寫
let str = "HeLLo WoRlD"
print(str.lowercased())
// 輸出:hello world
九拨黔、數(shù)組
1、以逗號拼接字符串?dāng)?shù)組所有元素為一個字符串
let arr = ["you", "only", "live", "once"]
let newArr = arr.joined(separator: ",")
print(newArr)
// 輸出
you,only,live,once
2绰沥、字符串轉(zhuǎn)數(shù)組
let str = "you only live once"
let arr = str.components(separatedBy: " ")
print(arr)
// 輸出
["you", "only", "live", "once"]
十篱蝇、輸入輸出參數(shù)(In-Out Parameter)
可以用inout定義一個輸入輸出參數(shù),在函數(shù)內(nèi)部修改外部變量的值
inout的本質(zhì)是地址傳遞(引用傳遞)
inout參數(shù)不能有默認(rèn)值
可變參數(shù)不能標(biāo)記為inout
inout參數(shù)的傳入值能被多次賦值
func swapValue(_ v1: inout Int, _ v2: inout Int) {
let tmp = v1
v1 = v2
v2 = tmp
}
var num1 = 10
var num2 = 20
swapValue(&num1, &num2)
print(num1, num2)
// 打印結(jié)果
// 20 10
十一徽曲、可變參數(shù)
參數(shù)類型后面加三個點表示可變參數(shù)
一個函數(shù)最多只能有1個可變參數(shù)
緊跟在可變參數(shù)后面的參數(shù)不能省略參數(shù)標(biāo)簽
func sum(_ numbers: Int..., other: Int) -> Int {
var total = 0
for item in numbers {
total += item
}
return total + other
}
let result = sum(1, 2, 3, 4, other: 5)
print(result)
// 打印結(jié)果
// 15
十二零截、屬性
嚴(yán)格來說,屬性可以按下面方式劃分
實例屬性(Instance Property)
1.存儲實例屬性(Stored Instance Property)存儲在實例的內(nèi)存中秃臣,每個實例都有1份
2.計算實例屬性(Computed Instance Property)類型屬性(Type Property)
1.存儲類型屬性(Stored Type Property)整個程序運行過程中涧衙,就只有1份內(nèi)存(類似于全局變量)
2.計算類型屬性(Computed Type Property)
十三哪工、mutating
結(jié)構(gòu)體和枚舉是值類型,默認(rèn)情況下弧哎,值類型的屬性不能被自身的實例方法修改
在 func 關(guān)鍵字前加 mutating 可以允許這種修改行為
// 結(jié)構(gòu)體
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(_ deltaX: Double, _ deltaY: Double) {
x += deltaX
y += deltaY
}
}
// 枚舉
enum StateSwitch {
case low, middle, high
mutating func next() {
switch self {
case .low:
self = .middle
case .middle:
self = .high
case .high:
self = .low
}
}
}
十四雁比、@discardableResult
調(diào)用有返回值的方法,如果沒有使用返回的值撤嫩,會有一個黃色的警告偎捎,如果想消除這個警告,可以在方法前面加上 @discardableResult
注:除非特殊需求序攘,建議非必要不要使用
@discardableResult func add(_ a: Int, _ b: Int) -> Int {
a + b
}
// 這樣直接調(diào)用就不會有警告了
add(10, 3)
十五茴她、class & static & final
1、被class修飾的類型方法程奠、下標(biāo)丈牢,允許被子類重寫
被static修飾的類型方法、下標(biāo)瞄沙,不允許被子類重寫
2赡麦、被class修飾的計算類型屬性,可以被子類重寫
被static修飾的類型屬性(存儲帕识、計算),不可以被子類重寫
3遂铡、被 final 修飾的方法肮疗、下標(biāo)、屬性扒接,禁止被重寫
被final修飾的類伪货,禁止被繼承
十六、(+) (-)
Swift 編譯器特性
// 兩個 Int 類型參數(shù)相加钾怔、相減
let dic: [String: (Int, Int) -> Int] = [
"sum": (+),
"minus": (-)
]
let result1 = dic["sum"]?(10, 5)
let result2 = dic["minus"]?(12, 5)
print(result1)
print(result2)
十七碱呼、Any / AnyObject
- Any:可以代表任意類型(枚舉、結(jié)構(gòu)體宗侦、類愚臀、也包括函數(shù)類型)
- AnyObject:可以代表任意 類 類型(在協(xié)議后面加上:AnyObject,代表只有類能遵守和這個協(xié)議)
十八矾利、數(shù)組姑裂、字典聲明
// 下面兩種聲明數(shù)組的方法完全等價
var arr = Array<Int>()
var arr = [Int]()
// 下面兩種聲明字典的方法完全等價
var dic = Dictionary<Int, Int>()
var dic = [Int: Int]()
十九、is男旗、as舶斧、as?、 as!
i s 用來判斷是否為某種類型察皇, as用來做類型強制轉(zhuǎn)換
二十茴厉、訪問控制(Access Control)
在訪問權(quán)限控制這塊,Swift提供了5個不同的訪問級別,以下是從高到低排列矾缓,實體指的是被訪問級別修飾的內(nèi)容
- open:允許在定義實體的模塊怀酷,其它模塊中訪問,允許其它模塊進行繼承而账、重寫(open只能用在類胰坟、類成員上)
- public:允許在定義實體的模塊、其它模塊中訪問泞辐、不允許其它模塊進行繼承笔横、重寫
- internal:只允許在定義實體的模塊中訪問,不允許在其它模塊中訪問
- fileprivate:只允許在定義實體的源文件中訪問
- private:只允許在定義實體的封閉聲明中訪問
注:絕大部分實體默認(rèn)都是 internal 級別
二十一咐吼、API可用性說明
比如你自己封裝了一個三方框架吹缔,但是在升級過程中有的API被廢棄掉,或者已過期锯茄,可以進行下面的操作
struct Student {
// 方法名重命名
@available(*, unavailable, renamed: "study")
func study1() {}
func study() {}
// 方法在iOS被廢棄掉
@available(iOS, deprecated: 11)
func run() {}
}
let stu = Student()
// 會提示 'run()' was deprecated in iOS 11
stu.run()
// 會提示 'study1()' has been renamed to 'study'
stu.study1()