一.基础语法:
Swift 是 iOS 和 OS X 应用开发的一门新语言。然而,如果你有 C 或者 Objective-C 开发经验的话,你会发现 Swift 的很多内容都是你熟悉的。
Swift 的类型是在 C 和 Objective-C 的基础上提出的,Int是整型;Double和Float是浮点型;Bool是布尔型;String是字符串。Swift 还有两个有用的集合类型,Array和Dictionary,请参考集合类型。
就像 C 语言一样,Swift 使用变量来进行存储并通过变量名来关联值。在 Swift 中,值不可变的变量有着广泛的应用,它们就是常量,而且比 C 语言的常量更强大。在 Swift 中,如果你要处理的值不需要改变,那使用常量可以让你的代码更加安全并且更好地表达你的意图。
除了我们熟悉的类型,Swift 还增加了 Objective-C 中没有的类型比如元组(Tuple)。元组可以让你创建或者传递一组数据,比如作为函数的返回值时,你可以用一个元组可以返回多个值。
Swift 还增加了可选(Optional)类型,用于处理值缺失的情况。可选表示“那儿有一个值,并且它等于 x ”或者“那儿没有值”。可选有点像在 Objective-C 中使用nil,但是它可以用在任何类型上,不仅仅是类。可选类型比 Objective-C 中的nil指针更加安全也更具表现力,它是 Swift 许多强大特性的重要组成部分。
Swift 是一个类型安全的语言,可选就是一个很好的例子。Swift 可以让你清楚地知道值的类型。如果你的代码期望得到一个String,类型安全会阻止你不小心传入一个Int。你可以在开发阶段尽早发现并修正错误。
变量和常量:
常量和变量把一个名字(比如maximumNumberOfLoginAttempts或者welcomeMessage)和一个指定类型的值(比如数字10或者字符串"Hello")关联起来。常量的值一旦设定就不能改变,而变量的值可以随意更改。
声明常量和变量:
常量和变量必须在使用前声明,用let来声明常量,用var来声明变量。下面的例子展示了如何用常量和变量来记录用户尝试登录的次数:
--------------------------------------------------------------------------------
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
--------------------------------------------------------------------------------
数值型字面量:
整数字面量可以被写作:
一个十进制数,没有前缀
一个二进制数,前缀是0b
一个八进制数,前缀是0o
一个十六进制数,前缀是0x
下面的所有整数字面量的十进制值都是17:
let decimalInteger = 17
let binaryInteger = 0b10001 // 二进制的17
let octalInteger = 0o21 // 八进制的17
let hexadecimalInteger = 0x11 // 十六进制的17
浮点字面量可以是十进制(没有前缀)或者是十六进制(前缀是0x)。小数点两边必须有至少一个十进制数字(或者是十六进制的数字)。浮点字面量还有一个可选的指数(exponent),在十进制浮点数中通过大写或者小写的e来指定,在十六进制浮点数中通过大写或者小写的p来指定。
如果一个十进制数的指数为exp,那这个数相当于基数和$10^{exp}$的乘积:
1.25e2 表示 $1.25 × 10^{2}$,等于 125.0。
1.25e-2 表示 $1.25 × 10^{-2}$,等于 0.0125。
如果一个十六进制数的指数为exp,那这个数相当于基数和$2^{exp}$的乘积:
0xFp2 表示 $15 × 2^{2}$,等于 60.0。
0xFp-2 表示 $15 × 2^{-2}$,等于 3.75。
下面的这些浮点字面量都等于十进制的12.1875:
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
数值类字面量可以包括额外的格式来增强可读性。整数和浮点数都可以添加额外的零并且包含下划线,并不会影响字面量:
--------------------------------------------------------------------------------
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
--------------------------------------------------------------------------------
元组
元组(tuples)把多个值组合成一个复合值。元组内的值可以使任意类型,并不要求是相同类型。
下面这个例子中,(404, "Not Found")是一个描述 HTTP 状态码(HTTP status code)的元组。HTTP 状态码是当你请求网页的时候 web 服务器返回的一个特殊值。如果你请求的网页不存在就会返回一个404 Not Found状态码。
let http404Error = (404, "Not Found") // http404Error 的类型是 (Int, String),值是 (404, "Not Found")
(404, "Not Found")元组把一个Int值和一个String值组合起来表示 HTTP 状态码的两个部分:一个数字和一个人类可读的描述。这个元组可以被描述为“一个类型为(Int, String)的元组”。
你可以把任意顺序的类型组合成一个元组,这个元组可以包含所有类型。只要你想,你可以创建一个类型为(Int, Int, Int)或者(String, Bool)或者其他任何你想要的组合的元组。
你可以将一个元组的内容分解(decompose)成单独的常量和变量,然后你就可以正常使用它们了:
let (statusCode, statusMessage) = http404Error
println("The status code is (statusCode)")
// 输出 "The status code is 404"
println("The status message is (statusMessage)")
// 输出 "The status message is Not Found"
如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记:
let (justTheStatusCode, _) = http404Error
println("The status code is (justTheStatusCode)")
// 输出 "The status code is 404"
此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:
println("The status code is (http404Error.0)") // 输出 "The status code is 404"
println("The status message is (http404Error.1)") // 输出 "The status message is Not Found"
你可以在定义元组的时候给单个元素命名:
let http200Status = (statusCode: 200, description: "OK")
给元组中的元素命名后,你可以通过名字来获取这些元素的值:
println("The status code is (http200Status.statusCode)") // 输出 "The status code is 200"
println("The status message is (http200Status.description)") // 输出 "The status message is OK"
作为函数返回值时,元组非常有用。一个用来获取网页的函数可能会返回一个(Int, String)元组来描述是否获取成功。和只能返回一个类型的值比较起来,一个包含两个不同类型值的元组可以让函数的返回信息更有用。请参考[函数参数与返回值(06_Functions.html#Function_Parameters_and_Return_Values)。
注意:元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。请参考类和结构体。
二 ,swif运算符
一.循环
常见的循环有:for/while/do while
1.for循环
1.1 OC中的for循环写法
for (int i = 0; i < 10; i++) {
}
1.2 swift中的写法
// 区间遍历 0..<10 0...9
for i in 0..<10 {
print(i)
}
for i in 0...9 {
print(i)
}
// 如果一个标识符不需要使用, 那么可以通过 _ 来代替
for _ in 0..<10 {
print("hello world")
}
2.while循环
2.1 OC中的写法
int a = 20
while (a) {
}
2.2 swift中的写法
2.2.1while后面的()可以省略
2.2.2没有非0(nil)即真
var i = 10
while i > 0 {
print(i)
i -= 1
}
3.do while循环
// 区别: 不再使用do while --> repeat while
var m = 0
repeat {
print(m)
m += 1
} while m < 10
二.字符串
1.字符串的介绍
1.1字符串在任何的开发中使用都是非常频繁的
1.2OC和Swift中字符串的区别
在OC中字符串类型时NSString,在Swift中字符串类型是String
OC中字符串@"",Swift中字符串""
1.3使用 String 的原因
String 是一个结构体,性能更高
NSString 是一个 OC 对象,性能略差
String 支持直接遍历
String 提供了 String 和 NSString之间的无缝转换
2.字符串的定义
2.1定义不可变字符串
let str = "hello swift"
2.2定义可变字符串
var strM = "hello world"
strM = "hello china"
3.获取字符串的长度
先获取字符集合,再获取集合的count属性
let length = str.characters.count
4.遍历字符串
for c in str.characters {
print(c)
}
5.字符串的拼接
5.1字符串之间的拼接
let str1 = "Hello"
let str2 = "World"
let str3 = str1 + str2
5.2字符串和其它标识符间的拼接
let name = "lgp"
let age = 18
let .98
let infoStr = "my name is (name), age is (age), height is (height)"
5.3字符串格式化
比如时间:03:04 如果显示 3 : 4 就不好.所以需要格式化
let min = 3
let second = 4
let timeStr = String(format: "%02d:%02d", arguments: [min, second])
6.字符串的截取
6.1简单的方式是将String转成NSString来使用
在标识符后加:as NSString即可
// 1.方式一: 将String类型转成NSString类型, 再进行截取
// (urlString as NSString) --> NSString
let header = (urlString as NSString).substringToIndex(3)
let footer = (urlString as NSString).substringFromIndex(10)
let range = NSMakeRange(4, 5)
let middle = (urlString as NSString).substringWithRange(range)
6.2Swift中提供了特殊的截取方式
该方式非常麻烦
Index创建较为麻烦
// 2.方式二: Swift原生方式进行截取
let headerIndex = urlString.startIndex.advancedBy(3)
let header1 = urlString.substringToIndex(headerIndex)
let footerIndex = urlString.endIndex.advancedBy(-3)
let footer1 = urlString.substringFromIndex(footerIndex)
let range1 = headerIndex.advancedBy(1)..
三.数组的使用
1.数组的介绍
1.1 数组(Array)是一串有序的由相同类型元素构成的集合
1.2 数组中的集合元素是有序的,可以重复出现
1.3 Swift中的数组
swift数组类型是Array,是一个泛型集合
2.数组的初始化
2.1 定义不可变数组,使用let修饰
注意:不可变数组要在定义的同时初始化,否则没有意义
let array = ["why", "yz"]
2.2 定义可变数组,使用var修饰
注意:数组是泛型集合,必须制定该数组中存放元素的类型
基本写法
var arrayM = Array
简单写法
var arrayM = [String]()
3.对可变数组的基本操作(增删改查)
3.1 添加元素
arrayM.append("ljp")
3.2 删除元素
let removeItem = arrayM.removeAtIndex(1) 返回值为删除的元素
arrayM.removeAll()
3.3 修改元素
arrayM[0] = "why"
3.4 查找元素(根据下标获取元素)
let item = arrayM[0]
4.数组的遍历
4.1 遍历下标值
for i in 0..
}
4.2遍历元素
for name in array {
print(name)
}
4.3遍历下标值和元素
for (index, name) in array.enumerate() {
print(index)
print(name)
}
5.数组的合并
相同类型的数组可以相加进行合并
可变数组和不可变的数组也能合并
let array1 = ["why", "yz"]
let array2 = ["lmj", "lnj"]
let resultArray = array1 + array2
四.字典的使用
1.字典的介绍
1.1字典允许按照某个键来访问元素
1.2字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合
1.3键集合是不能有重复元素的,而值集合是可以重复的,键和值是成对出现的
1.4Swift中的字典
Swift字典类型是Dictionary,也是一个泛型集合
2.字典的初始化
2.1 定义不可变字典,使用let修饰
注意:不可变字典要在定义的同时初始化,否则没有意义
系统会根据[]中存放的是键值对,还是一个个元素,来判断该[]是一个数组还是字典
let dict = ["name" : "why", "age" : 18, "height" : 1.88]
2.2 定义可变字典,使用var修饰
注意:字典是泛型集合,必须制定该数组中存放元素的类型
基本写法
var dictM = Dictionary
简单写法
var dictM = [String : NSObject]() // 常见
3.对可变字典的基本操作(增删改查)
3.1 添加元素
dictM.updateValue("why", forKey: "name")
3.2 删除元素
dictM.removeValueForKey("age")
3.3 修改元素
//如果原有没有对应的key/value, 那么就添加键值对
// 如果原有已经有对应的key/value, 那么直接修改
dictM.updateValue("1.77", forKey: "height")
dictM["name"] = "why"
3.4 查找元素(获取元素)
let item = dictM["name"]
4.字典的遍历
4.1 遍历字典中所有的key
for key in dict.keys {
print(key)
}
4.2 遍历字典中所有的value
for value in dict.values {
print(value)
}
4.3 遍历字典中所有的key / value
for (key, value) in dict {
print(key)
print(value)
}
5.字典的合并
相同类型的字典也不可以相加进行合并
可以把其中一个字典改为可变的,遍历不可变得字典,把元素一个一个的添加到另一个不可变字典中
let dict1 = ["name" : "why", "age" : 18]
var dict2 = ["height" : 1.88, "phoneNum" : "+86 110"]
for (key, value) in dict1 {
dict2[key] = value
}
五.元组的使用
1.元组的介绍
1.1元组是Swift中特有的,OC中并没有相关类型
1.2它是什么呢?
1.2.1 它是一种数据结构,在数学中应用广泛
1.2.2 类似于数组或者字典
1.2.3 可以用于定义一组数据
1.2.4 组成元组类型的数据可以称为“元素”
2.为什么使用元组?
如果字典或数组保存多种数据类型,那么从字典会数组取出来的数据类型是NSObject,我们使用的时候很不方便,要先转换为真实类型
元组保存多种数据类型,取出来就是该数据的真实类型,不需要转换就能直接使用
3.元组的定义
let infoTuple = ("why", 18, 1.88, "+86 110")
// 使用元组描述一个人的信息
("1001", "张三", 30, 90)
// 给元素加上元素名称,之后可以通过元素名称访问元素
(id:"1001", name:"张三", english_score:30, chinese_score:90)
构造函数基础
构造函数 是一种特殊的函数,主要用来在创建对象时初始化对象,为对象 成员变量 设置初始值,在 OC 中的构造函数是 initWithXXX,在 Swift 中由于支持函数 重载 ,所有的构造函数都是 init
构造函数的作用
分配空间 alloc
设置初始值 init
必选属性
自定义 Person 对象
class Person: NSObject {
/// 姓名
var name: String
/// 年龄
var age: Int
}
提示错误 Class 'Person' has no initializers -> 'Person' 类没有实例化器s
原因:如果一个类中定义了必选属性,必须通过构造函数为这些必选属性分配空间并且设置初始值
重写 父类的构造函数
/// `重写`父类的构造函数
override init() {
}
提示错误 Property 'self.name' not initialized at implicitly generated super.init call -> 属性 'self.name' 没有在隐式生成的 super.init 调用前被初始化
手动添加 super.init() 调用
/// `重写`父类的构造函数
override init() {
super.init()
}
提示错误 Property 'self.name' not initialized at super.init call -> 属性 'self.name' 没有在 super.init 调用前被初始化
为必选属性设置初始值
/// `重写`父类的构造函数
override init() {
name = "张三"
age = 18
super.init()
}
小结
非 Optional 属性,都必须在构造函数中设置初始值,从而保证对象在被实例化的时候,属性都被正确初始化
在调用父类构造函数之前,必须保证本类的属性都已经完成初始化
Swift 中的构造函数不用写 func
子类的构造函数
自定义子类时,需要在构造函数中,首先为本类定义的属性设置初始值
然后再调用父类的构造函数,初始化父类中定义的属性
/// 学生类
class Student: Person {
/// 学号
var no: String
override init() {
no = "001"
super.init()
}
}
小结
先调用本类的构造函数初始化本类的属性
然后调用父类的构造函数初始化父类的属性
Xcode 7 beta 5之后,父类的构造函数会被自动调用,强烈建议写 super.init() ,保持代码执行线索的可读性
super.init() 必须放在本类属性初始化的后面,保证本类属性全部初始化完成
Optional 属性
将对象属性类型设置为 Optional
class Person: NSObject {
/// 姓名
var name: String?
/// 年龄
var age: Int?
}
可选属性 不需要设置初始值,默认初始值都是 nil
可选属性 是在设置数值的时候才分配空间的,是延迟分配空间的,更加符合移动开发中延迟创建的原则
重载构造函数
Swift 中支持函数重载,同样的函数名,不一样的参数类型
/// `重载`构造函数
///
/// - parameter name: 姓名
/// - parameter age: 年龄
///
/// - returns: Person 对象
init(name: String, age: Int) {
self.name = name
self.age = age
super.init()
}
注意事项
如果重载了构造函数,但是没有实现默认的构造函数 init() ,则系统不再提供默认的构造函数
原因,在实例化对象时,必须通过构造函数为对象属性分配空间和设置初始值,对于存在必选参数的类而言,默认的 init() 无法完成分配空间和设置初始值的工作
调整子类的构造函数
重写 父类的构造函数
/// `重写`父类构造函数
///
/// - parameter name: 姓名
/// - parameter age: 年龄
///
/// - returns: Student 对象
override init(name: String, age: Int) {
no = "002"
super.init(name: name, age: age)
}
重载 构造函数
/// `重载`构造函数
///
/// - parameter name: 姓名
/// - parameter age: 年龄
/// - parameter no: 学号
///
/// - returns: Student 对象
init(name: String, age: Int, no: String) {
self.no = no
super.init(name: name, age: age)
}
注意:如果是重载的构造函数,必须 super 以完成父类属性的初始化工作
重载 和 重写
重载 ,函数名相同,参数名/参数类型/参数个数不同
重载函数并不仅仅局限于 构造函数
函数重载是面相对象程序设计语言的重要标志
函数重载能够简化程序员的记忆
OC 不支持函数重载,OC 的替代方式是 withXXX...
重写 ,子类需要在父类拥有方法的基础上进行扩展,需要 override 关键字
荒野乱斗国际版 (BrawlStars)最新版本v56.274
下载一波超人内置修改器菜单版 安卓版v1.0.2
下载敢达决战官方正版 安卓版v6.7.9
下载敢达决战 安卓版v6.7.9
下载继承了一座戏园子无限声望铜钱版 内置菜单最新版v1.7
继承了一座戏园子折相思版是游戏的破解版本,在该版本中为玩家提
山河半世橙光清软金手指版 无限鲜花v3.24
山河半世是一款超级好玩的橙光恋爱游戏,在游戏中玩家们需要扮演
蓬莱手游折相思版 安卓版v1.0.0
蓬莱免广告版是游戏的修改版本,在该版本中为玩家去除了广告,玩
当红影后橙光游戏破解版2025 最新版v1.0
当红影后橙光破解版是一款超级好玩的娱乐圈题材的橙光游戏,在这
忽然成了万人迷清软完结版 无限鲜花版v12.15
忽然成了万人迷破解版是一款非常好玩的男性向橙光游戏,在有一天