Swift语言是苹果在2014发布的,而且苹果力推开发者使用其来开发APP。所有在此提供一套Swift2.0中文手册供大家使用
:!Swift 2.0 中文手册.pdf
swift 中布局十分严格 切记要注意 左右一定要对称
使用注意:
- 1.语句末尾不用使用
;
- 2.在 Swift 中使用
print()
替代 OC 中的NSLog
- 3.在swift中访问属性和调用方法都是通过.来进行的
- 4.在 Swift 中要实例化一个对象可以使用
类名()
的格式,与 OC 中的alloc/init
等价 - 5.OC 中的
[[类名 alloc] initWithXXX]
,[类名 类名WithXXX]
在 Swift 中通常可以使用类名(XXX: )
找到对应的函数 - 6.OC 中的
[UIColor redColor]
类方法,在 Swift 中通常可以使用类名.XXX()
找到对应的函数
1.变量和常量
2.类型推导和类型装换
自动推导
- swift 对数据类型要求异常严格
- swift能够根据右边的代码,推导出变量的准确类型
- 如果要指定变量,可以在变量名后使用
: 类型
- Int类型分为好几种,Int8, Int16, Int32, Int64,因为类型严格,Int8和Int16不能进行运算,所以建议以后开发中都使用Int
3.字符串 String
- 是一个结构体,性能高于NSString
- String 支持直接遍历
- String 目前具有了绝大多数 NSString 的功能
- String和NSString转换方便
- OC定义字符串
/*:
OC的字符串:
NSString *str = @"hello";
格式化字符串: [NSString stringWithFormat:@"%.02f", 3.14159]
swift中定义字符串:
var 变量名 = "hello"
*/
- 字符串中的常用方法
4.Optional可选
5.if条件分支
6.循环
7.switch
8.数组
9.元组
10.字典
11.枚举
12函数
- 函数的定义
func 函数名(形参名1: 形参类型1, 形参名2: 形参类型2, ...) `->` 返回值 { // 代码实现 } /*函数如果没有返回值: 1. 省略 2. -> Void 3. -> () 外部参数名,作用能够方便调用人员更好地理解函数的语义 带外部参数名的参数列表格式: (外部参数名1 形式参数名1: 参数类型1, 外部参数名2 形式参数名2: 参数类型2, ...)*/
- 函数定义和调用
//: 定义函数
func sum(a: Int, b: Int) -> Int { return a + b } //: 调用函数, b表示外部参数名 sum(10, b: 20) //: 没有返回值 func sayHello() -> () { print("hello") } sayHello()
- 外部参数名
- 在形参名前再增加一个外部参数名,能够方便调用人员更好地理解函数的语义
- swift2.0默认帮我们生成除第一个参数外的所有外部参数名
//: 为什么有外部参数名呢?
func addStudent(name: String, age: Int, number: Int) { print("name = \(name), age = \(age), number = \(number)") } //: 如果没有外部参数名,我们很难判断每个参数的作用 //addStudent("liudehua", 54, 53) //: 有外部参数名,每个参数的作用一目了然,swift2.0默认帮我们生成除第一个参数外的所有外部参数名 addStudent("liudehua", age: 54, number: 53) //: 指定外部参数名 func addStudent2(stu_name name: String, stu_age age: Int, stu_number number: Int) { print("name = \(name), age = \(age), number = \(number)") } addStudent2(stu_name: "liudehua", stu_age: 54, stu_number: 53)
- 函数返回元组类型
/*:
在c语言中要返回多个值:
1.传参数时传入指针,在函数内部修改该指针指向的值
2.返回一个结构体
3.返回数组
*/
//: 在swift中可以通过返回元组来方便的返回多个值
func getStudent() -> (String, Int, Int) { return ("liudehua", 54, 53) } //: student是一个(String, Int, Int)的元组 let student = getStudent() //: 可以通过.0 .1 来访问 student.0 student.1 //: 函数通过元组返回多个值,并且为元组中的元素取名成,方便调用 func getStudent2() -> (name: String, age: Int, num: Int) { return ("liudehua", 54, 53) } let student2 = getStudent2() student2.name student2.age
闭包
闭包类似于 OC 中的 Block,是一段预先定义好的代码,在需要时执行
定义
- 闭包表达式格式:
{ (形参名称1: 形参类型1, 形参名称2: 形参类型2, ...) -> 返回值 `in` //要执行的代码 }
-
in
用于区分闭包定义和代码实现
定义闭包
// 定义闭包
var closure = { (text: String) -> Void in }
调用闭包
// 调用闭包
closure("学习闭包")
闭包使用场景(回调)
- 模拟耗时操作
// 闭包的使用场景: 回调
// 在子线程执行完任务后通知调用者
func loadData(finished: (result: String) -> Void) { dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in print("拼命加载数据: \(NSThread.currentThread())") dispatch_async(dispatch_get_main_queue(), { () -> Void in print(": \(NSThread.currentThread())") // 通知调用者 finished(result: "获取到20条数据") }) } }
- 调用
loadData { (result) -> Void in
print("网络请求完成: \(result)") }
类的定义
- OC中的类
在OC中一个类包涵.h和.m两个文件
.h:
@interface 类名: 父类名
@end
.m:
@implement 类名
@end
实例化类:
类名 *变量名 = [[类名 alloc] init];
- swift 定义类格式
- ()里面是空,表示调用类的默认构造函数 = [[类名 alloc] init];
- swift中访问属性通过点语法来访问, 方法也是通过点语法来调用
- 继承和OC一样,通过 : 来继承, swift也只有单继承
class 类名: 父类名 {
//: 一些属性
//: 一些方法
}
实例化一个类:
var 变量名 = 类名() 注意: 1swift的继承和oc一样是通过:, swift也只有单继承 2.访问类的属性和调用类的方法都是通过.来进行的 3.覆盖父类方法, 需要加关键字 override
- 定义
Person
类:
//: 定义一个类, 没有继承任何类的类,称之为 基类,超类
class Person: NSObject { // 名称属性 var name = "liudehua" // 年龄 var age = 54 // 身高 var height = 1.78 // 体重 var weight = 70.0 // 方法 func sleep() { print("累了,睡觉") } func eat() { print("饿了,吃饭") } }
- 实例化
Person
类
// 实例化类Person
var p = Person()
// 访问属性
print(p.name) // 修改属性 p.name = "zhangsan" print("名称修改后:\(p.name)") // 调用方法 p.sleep()
- 定义
Student
继承Person
//: 继承 和OC 一样通过 : 来实现继承
class Student: Person { // 班级属性 var grade = "ios05期" // 定义学习方法 func study() { print("开开心心学习,高薪就业") } // 覆盖父类方法, 需要加关键字 override override func sleep() { print("学习累了,睡觉") } }
- 实例化Student
// 实例化Student
let s = Student()
print(s.grade)
// 调用Student的sleep s.sleep()
类的属性
- oc中的属性:
@property(noatomic, copy) NSString *name;
1.在.h声明 getter 和 setter 方法
2.在.m实现 getter 和 setter 方法
3.在.m生成 _成员变量
存数型属性
: 存储数据
属性监视器
: 当存储型属性发生改变的时候,通知我们属性发生了改变
-
willSet
: 在属性将要发生改变时调用 -
didSet
: 在属性已经发生改变时调用
计算型属性
: 不存储任何数据,通过get方法来返回一个计算好的数据通过set方法来设置一个存储型属性的值,当只提供get方法时,称之为只读计算属性.必须要有get方法
计算型属性
相当于OC
中的@property
生成的getter
和setter
方法,只不过setter
方法没有给_成员变量
赋值
@interface Person ()
@property (nonatomic, assign) CGFloat heightCM; @end @implementation Person // getter - (CGFloat)heightCM { return ; } // setter - (void)setHeightCM:(CGFloat)heightCM { // 没有 _heightCM = heightCM }
类属性
: 不管创建多少个实例,都共享这个属性
- 定义:在类属性前面加
class
关键字,类属性只能是计算型属性 - 访问方法:
类名
.属性名
存储型属性、计算型属性
class Person {
//: 存储型属性
var name = "liudehua" // //: 存储型属性,单位是m var height = 1.74 // //: 计算型属性 var heightCM: Double { get { return height * 100 } set { height = newValue / 100 } } // //: 存储型属性 var age = 54 // //: 存储型属性 var weight: Float = 70 {
//: 在属性将要发生改变时调用 willSet { print("weight willSet") } //在属性已经发生改变时调用 didSet { print("weight didSet") } } // //: 定义一个sleep方法 func sleep() { print("person 累了, sleep...") } // //: 定义一个eat方法 func eat() { print("person 饿了, eat...") } } // 实例化Person var person = Person() person.height person.heightCM = 178 person.height person.weight = 72 var person2 = Person() //: person的weight属性和person2的weight没有关系,相互独立的. person2.weight = 60 print(person2.weight)
类属性
//: 定义圆
class Circle {
//: 只要是圆就有圆周率,圆周率的值固定不变,不管创建多少个实例,都共享这个圆周率属性 //: 类型属性: 只读计算型属性 class var pi: Double { return 3.141592653 } // var radius = 20.0 // //: 周长,只读计算型属性 var perimeter: Double { return 2 * Circle.pi * radius } } // //Circle.pi = 1 // var pingpong = Circle() pingpong.perimeter // pingpong.radius = 40 pingpong.perimeter
构造函数
自定义 Car
对象
class Person {
var name: String }
- 以上代码会报:“存储性属性没有初始化值”,原因是在swift中类实例化后,所有的
存储型属性
必须有值 - 解决方法1:定义属性时赋值
class Person {
// 直接赋值
var name: String = "liudehua" } // 实例化 var p1 = Person() p1.name // 实例化 var p2 = Person() p2.name //: 实例化出来对象 name属性都一样,显然不合理.
- 解决方法2:将对象属性类型设置为
Optional
class Person {
var name: String? } var p = Person() p.name = "liudehua" print(p.name) //: 用可选的,打印出来都带Optional
- 输出结果:Optional("liudehua")
- 有没有什么办法,在类的实例化过程中,给存储型属性设置指定的值?,实例化后直接拿来用.或者在类实例化时指定存储型属性的值
利用 init
函数为属性初始化
- 在swift中对象是通过构造函数来实例化的.构造函数的作用:在对象实例化过程中给所有的存储型属性设置初始值,并且执行必要的准备和初始化任务.
class Person: NSObject {
var name: String var age: Int //: 重写父类构造函数 override init() { print("init") name = "liudehua" age = 22 } }
重载构造函数
- swift 中支持函数重载,同样的函数名,不一样的参数类型
//: 重载构造函数
init(name: String, age: Int) {
self.name = name self.age = age }
子类构造函数
- 自定义子类时,需要在构造函数中,首先为本类定义的属性设置初始值
- 再调用父类的构造函数,初始化父类中定义的属性
- 如果子类没有去实现构造函数,会继承父类的构造函数
- 如果子类实现了构造函数,不会继承父类的构造函数
class Stuent: Person {
var grade: String // 子类构造函数需要调用父类构造函数 // 需要先初始化子类属性,在调用父类构造函数 init(name: String, age: Int, grade: String) { self.grade = grade super.init(name: name, age: age) } }
convenience 构造函数
便利构造函数: 它是辅助性的构造函数.方便创建对象
- 默认情况下,所有的构造函数都是指定构造函数
Designated
convenience
关键字修饰的构造方法就是便利构造函数- 便捷构造函数可以返回
nil
- 需要调用本类的一个指定构造函数
/// 方便创建ios05期学生
convenience init?(stuName: String, stuAge: Int) {
// 判断age是否合法 if stuAge < 0 || stuAge > 130 { print("年龄不合法") return nil } self.init(name: stuName, age: stuAge, grade: "ios05期") }
构造函数小结
- 1.不需要func关键字.名称是固定的,都叫 init
- 2.当类没有实现构造函数时,系统会添加一个默认的构造函数.
- 3.如果实现了构造函数,系统就不会添加默认构造函数
- 4.如果子类没有实现构造函数.会继承父类的构造函数
- 5.子类构造函数需要调用父类构造函数
- 6.需要先初始化子类属性,在调用父类构造函数
- 7.子类一旦实现了构造函数.就不会继承父类的构造函数
懒加载
在 iOS 开发中,懒加载是无处不在的
- 方法1
lazy var p = Person()
- 方法2
// 方法2, 需要指定p的类型
lazy var p: Person = {
let person = Person() return person }()
- 测试调用
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { p.name = "lisi" print("p.name: \(p.name)") }
Person
类
class Person: NSObject {
var name: String? override init() { print("初始化") } }