Swift3.0从入门到放弃(三)
2017-02-21 03:44
295 查看
Swift当中的函数
Swift中函数的简单定义
Swift中函数参数的使用
Swift中的枚举
Swift中如何定义一个枚举
Swift中的结构体
Swift中结构体的基本使用
Swift中的类
Swift中类的定义
Swift中多种属性
Swift中的属性监听器
Swift中的构造函数
Swift中的析构函数
Swift中的循环引用问题
Swift中的可选链
Swift中协议的基本使用
Swift中函数的简单定义
Swift中函数参数的使用
Swift中的枚举
Swift中如何定义一个枚举
Swift中的结构体
Swift中结构体的基本使用
Swift中的类
Swift中类的定义
Swift中多种属性
Swift中的属性监听器
Swift中的构造函数
Swift中的析构函数
Swift中的循环引用问题
Swift中的可选链
Swift中协议的基本使用
Swift当中的函数
关于Swift中的函数的叫法来自于官方文档function(函数)和method(方法),和OC中的方法C中的函数基本差不多,大体可以分为无参无返、有参无返、无参有返和有参有返四中类型。
Swift中函数的简单定义
// Swift中的函数定义格式为: // func 函数名(参数列表) -> 返回值类型 { // 代码块 // return 返回值 // } // 无参无返回 func eat() ->Void { // 当没有返回值时 -> void 可以省略 print("正在吃饭"); } // 有参无返 func eatWith(food : String) { print("正在吃\(food)"); } // 无参有返 func receiveMessage() -> String { return "10086" } // 有参有返 func getSumWith(num1 : Int, num2 : Int) ->Int { return num1 + num2 } // 函数调用 eat() eatWith(food: "油条") print(receiveMessage()) print(getSumWith(num1: 10, num2: 20))
Swift中函数参数的使用
import UIKit // 外部和内部参数 // 外部参数:可以在函数外部看见参数名称的参数叫做外部参数 // 内部参数:只能在函数内部看见参数名称的参数叫做内部参数 // 在Swift3.0中,函数中的参数默认既是外部参数又是内部参数 func calculate(num1 : Int, num2 : Int) -> Int { return num1 + num2 } func calculate1(tmp1 num1 : Int, tmp2 num2 : Int) -> Int { return num1 + num2 } func calculate2(_ num1 : Int, _ num2 : Int) -> Int { return num1 + num2 } calculate(num1: 10, num2: 20) // 此时num1、num2既是外部参数也是内部参数 calculate1(tmp1: 20, tmp2: 10) // 此时tmp1、tmp2是外部变量,相当于num1和num2起的别名,num1和num2为内部变量 calculate2(30, 20) // 在函数参数名前面加上下划线,可将函数参数变为内部变量 // 可变参数 // 在参数类型后面加上 ... 可将参数变为可变参数,参数的个数由一个到多个不等,此时的nums是数组类型 func calculateWithNums(_ nums : Int...) ->Int { var sum = 0 for num in nums { sum += num } return sum } calculateWithNums(20,10,11,32) // 默认参数 func getCoffeeWithName(_ name : String = "雀巢") -> String { return "获得一杯\(name)" } getCoffeeWithName() // 获得一杯雀巢 如果不传参数 就是用参数默认值 // 指针参数 // 函数的参数传入的是内存地址 在参数的类型前面加上 inout 关键词 func exchangeNums(_ num1 : inout Int, _ num2 : inout Int ) { let tmp = num1 num1 = num2 num2 = tmp } var num1 = 10; var num2 = 20 print("num1 = \(num1) num2 = \(num2)") // num1 = 10 num2 = 20 exchangeNums(&num1, &num2) print("num1 = \(num1) num2 = \(num2)") // num1 = 20 num1 = 10
Swift中的枚举
枚举是定义了一个通用类型的一组相关的值,可以在代码中以安全的方式使用这些值。 在C和OC当中枚举是指定相关名称为整型值(有名字的常量)。 在Swift中枚举更加的灵活,不必给每一个枚举成员提供一个值,也可以提供值为字符串,字符,或是整型和浮点型。
Swift中如何定义一个枚举
import UIKit // 定义一个枚举 enum GenderType { case male case female case unknown } // 如何使用枚举的值 let gender_01 : GenderType = .male // 根据上下文能够推导出枚举类型,可以直接写.真实类型 let gender_02 : GenderType = GenderType.female // 也可以写 枚举类型.真实类型 // 如何给枚举成员赋值 enum DirectionType : String { // 赋值前 必须在枚举类型后面标注枚举成员赋值的类型 case east = "east" case south = "south" case west = "west" case north = "north" } let dir = DirectionType(rawValue: "south") // DirectionType? if let dir = DirectionType(rawValue: "west") { // 由于返回值可能为nil 所以是可选类型 print(dir.rawValue) } // 枚举类型的定义方式二 enum CoffeeType : Int { case nescafe = 0, cappuccino, mocha } print(CoffeeType.cappuccino.rawValue) // 枚举成员值的类型若为Int型,赋值一个,后面的自动自增
Swift中的结构体
结构体(struct)是由一系列相同类型或不同类型的数据构成的数据集合,结构体是值类型,在方法和函数中是值传递。
Swift中结构体的基本使用
import UIKit // 1.定义一个结构体 struct HWLocation { // 属性 var x : Double var y : Double } // 2.结构体的创建 let struct_01 = HWLocation(x: 10, y: 20) // 3.给结构体扩充方法 struct Location { // 属性 var x : Double var y : Double // 扩充方法一 // 打印坐标方法 func printLocation() { print("Location x : \(self.x) y : \(self.y)") } // 扩充方法二 // 更改坐标方法 (扩充函数中涉及修改属性值时 函数前必须添加 mutating 关键字) // mutating 变化 mutating func changeLocation(_ x : Double, _ y : Double) { self.x = x self.y = y } } var struct_02 = Location.init(x: 20, y: 100) struct_02.printLocation() // 结构体扩充方法调用 struct_02.changeLocation(9, 9) // 结构体扩充方法 修改属性的值 (PS: 结构体必须由var可变修饰才能更改) print(struct_02) // Location(x: 9.0, y: 9.0) 修改成功 // 4.给结构体扩充构造函数 (系统默认会给结构体扩充全属性赋值构造函数) // 注意 : 构造函数必须以init开头;构造函数不需要写返回值;在构造函数中必须对每一个属性进行初始化 struct Registration { var userName : String var userAge : Int var ID_card : String var email : String // 扩充构造方法 init(_ userName : String = "用户名", _ userAge : Int = 18, _ ID_card : String = "666", _ email : String = "123.qq.com") { self.userName = userName self.userAge = userAge self.ID_card = ID_card self.email = email } } let register = Registration("香格里拉", 20) print(register)
Swift中的类
Swift也是一门面向对象的语言,若想实例化对象必须要用到类,在Swift当中我们用关键词class来定义一个类。
Swift中类的定义
import UIKit // 定义一个简单的Person类,Prson类可以不继承任何类,主要看是否需要用到父类的属性和方法。 // 如果用不到父类的属性和方法,那就可以不继承,使得当前类更轻量级。 // 系统会自动给类扩展一个构造方法,但是并不会自动初始化类中的属性。 // 所以对于类中的属性 1.可以定义时进行初始化、2.定义成可选类型、3.在init构造方法中进行手动初始化。 // 个人经验 : 如果属性是对象类型(UIView、NSUrl等)写成可选类型;如果是值类型(Int、 String等)直接定义时进行初始化。 class Person : NSObject { var name : String var age : Int // 重写构造方法 在方法前面加上 override override init() { name = "陈冠希" age = 18 } } // 创建Person对象 let p = Person() print("姓名:\(p.name) 年龄:\(p.age)")
Swift中多种属性
在Swift中类的属性大体分为三种:存储属性、计算属性、类属性。
import UIKit class Person : NSObject { // 存储属性 : 用来存储实例的常量和变量 var name : String = "张柏芝" var age : Int = 0 var mathScore : Double = 59.9 var englishScore : Double = 70.0 // 计算属性 不同点是赋值的是一个大括号 大括号内可以有计算属性的get和set方法 // 一般不会用到set方法 若只有返回值(get方法or只读属性) 可以省略set和get方法 直接return // 计算属性完整写法 var averageScore : Double { set { } get { return (mathScore + englishScore) * 0.5 } } // 计算属性省略写法 var printInfo : String { return "姓名:\(name) 年龄:\(age) 数学成绩:\(mathScore) 英语成绩:\(englishScore)" } // 类属性 是和整个类相关的属性 并且使用类名进行访问 static var courseCount : Int = 2 } // 创建人类的对象 let p = Person() // 访问存储属性 print(p.name) // 访问计算属性 print(p.averageScore) // 访问类属性 print(Person.courseCount)
Swift中的属性监听器
import UIKit // 在Swift中对类中属性的监听操作可以用属性监听器 在OC当中一般利用属性的get方法进行监听 class Person : NSObject { var name : String = "" { // 属性即将发生改变 // willSet { // print("属性即将发生改变 旧值:\(name) 新值:\(newValue)") // } willSet(newName) { // 在即将发生变化监听器中 可将系统提供的 newValue 起别名 print("属性即将发生改变 旧值:\(name) 新值:\(newName)") } // 属性发生改变 // didSet { // print("属性发生改变 旧值:\(oldValue) 新值:\(name)") // } didSet(oldName) { // 在发生变化监听器中 可将系统提供的 oldValue 起别名 print("属性发生改变 旧值:\(oldName) 新值:\(name)") } } } // 创建人类对象 let p = Person() // 属性发生变化 触发属性监听器 p.name = "小布什" p.name = "奥巴马"
Swift中的构造函数
import UIKit // 定义人类 class Person : NSObject { var name : String = "" var age : Int = 0 var height : Double = 0.0 // 被覆盖的自带构造函数 可手动再扩展一个 // override init() { // // } // 自定义构造函数(一旦自定义构造函数,编辑器自动给类扩展的构造函数将会被覆盖) // 构造函数中,要用到属性时,可以省略self. 但是若出现命名冲突时,必须加上self. init(name : String, age : Int, height : Double) { self.name = name self.age = age self.height = height } // 复杂版的字典转模型构造方法 (但是灵活性不好) // init(dict : [String : Any]) { // // if let tmpName = dict["name"] as? String { // self.name = tmpName // } else { // self.name = "" // } // // if let tmpAge = dict["age"] as? Int { // self.age = tmpAge // } else { // self.age = 0 // } // // if let tmpHeight = dict["height"] as? Double { // self.height = tmpHeight // } else { // self.height = 0.0 // } // // } // 利用KVC方式字典转模型赋值 (KVC属于NSObject的方法,所以必须继承自NSObject才能使用) init(dict : [String : Any]) { super.init() // 在调用KVC方法前 调用super的init方法 setValuesForKeys(dict) } // 避免KVC找不到对应的key值报错 空实现系统以下方法 override func setValue(_ value: Any?, forUndefinedKey key: String) {} } // 创建人类对象 //let p = Person(name: "陈冠希", age: 18, height: 1.88) //print(p.name, p.age, p.height) // 通过字典给Person对象赋值 let dict : [String : Any] = ["name" : "谢霆锋", "age" : 19, "height" : 1.88] let p2 = Person(dict: dict) print(p2.name, p2.age, p2.height)
Swift中的析构函数
Swift中的析构函数其实就是OC中的dealloc方法,在ARC下不可手动调用。Swift通过自动引用计数来处理实例对象的内存管理,当一个实例对象的引用计数为0时,系统会自动调用该对象的析构函数。通常在西沟函数中,会释放一些资源,如监听通知的对象等。
mport UIKit class Person : NSObject { deinit { print("人被释放了") } } var p : Person? = Person() p = nil // 当一个实例对象被释放时,系统自动调用该对象的析构函数
Swift中的循环引用问题
在Swift中系统也是通过实例对象的引用计数来管理内存的,当一个对象被强引用时,引用计数+1,当强引用消失时,引用计数-1;在实例对象的引用计数为0时,对象被释放。但是在ARC下也有可能发生内存泄漏问题,比如出现循环引用。
import UIKit // 创建Person类 class Person : NSObject { var name : String = "" // var book : Book? weak var book : Book? // 改为若引用 deinit { print("人已经被销毁") } } // 创建Book类 class Book : NSObject { var name : String = "" var owner : Person? deinit { print("书已经被销毁") } } // 创建书对象 & 人对象 var book : Book? = Book() var p : Person? = Person() p?.book = book book?.owner = p // 当我们把实例对象的强应用去掉后 发现被没有调用两个对象的析构函数 证明此时两个对象都未被释放 // 解决方案一 : 在其中一个对象中将引用另一个对象的属性前面添加 weak 变为若引用 // 解决方案二 : 使用 unowned 关键词修饰也可以 但是不安全 基本不用 p = nil book = nil
Swift中的可选链
import UIKit // 可选链 : 多个可选类型组成的链条叫做可选链 // ?.就是可选链,系统会对可选链中的每个环节进行自动判断,当可选类型有值就进行解包, // 当可选类型为空时就赋值为nil,所以对于整个可选链语句的返回值不是nil就是一个可选类型。 // 运用可选连当其中的某个环节为nil时,整个可选链条就会失效 class Person : NSObject { var name : String = "" var dog : Dog? } class Dog : NSObject { var name : String = "" var toy : Toy? } class Toy : NSObject { var name : String = "" var price : Double = 0 func flying() { print("飞盘在非") } } // 实例化对象 let person = Person() let dog = Dog() let toy = Toy() dog.toy = toy person.dog = dog // 1.取值 // 1.1危险方式(强制解包) print(person.dog!.toy!.price) // 1.2复杂层层可选绑定方式 if let d = person.dog { if let t = d.toy { print(t.price) } } // 1.3可选链方式取值 if let price = person.dog?.toy?.price { print(price); } // 2.通过可选链赋值 (强制解包和层层绑定方式大体如上) person.dog?.toy?.price = 9.99 if let price = person.dog?.toy?.price { print(price); } // 3.通过可选链调用函数 (强制解包和层层绑定方式大体如上) person.dog?.toy?.flying()
Swift中协议的基本使用
import UIKit // 1. 定义一个协议 protocol TestProtocol { // 协议中提供的函数声明 func eat() func sleep() } // 1.1 如果一个类不继承自任何其他类 那么在类名后面加上 : 协议名称 来遵守协议 class person : TestProtocol { // 实现协议中的方法 func eat() { print("吃饭") } func sleep() { print("睡觉") } } // 1.2 如果一个类有父类 就在继承的父类后面加上 ,协议名称 来遵守协议 class Student : NSObject, TestProtocol { // 实现协议中的方法 func eat() { print("吃饭") } func sleep() { print("睡觉") } } // 2. 协议在代理模式中的使用 协议后面加上 :class 规定此协议只能被类遵守(避免被枚举、结构体等遵守与类中代理属性weak修饰词冲突) protocol DriverProtocol : class { func drivering() } class Boss : NSObject { // 定义代理属性 用weak修饰 防止循环引用 weak var driver : DriverProtocol? func goHome() { driver?.drivering() // 让遵守协议的人开车送老板回家 } } class Driver : NSObject, DriverProtocol { func drivering() { print("开车") } } let boss = Boss() let driver = Driver() boss.driver = driver boss.goHome() // 开车 // 3. 将协议中的方法设置成 optional 类型 // 可以使用 optional 关键字修饰协议中可选择实现的方法,但是optional是OC中的特性,所以必须在协议的前面 // 加上@objc(Swift2.0)、在方法的 optional 关键字前面也加上 @objc(Swift3.0) @objc protocol Test2Protocol : class { func RequiredFunc() // 必须实现的方法 @objc optional func optionalFunc() // 可选择实现的电方法 } class Teacher : NSObject, Test2Protocol { func RequiredFunc() { print("必须实现的方法") } }
相关文章推荐
- Swift3.0从入门到放弃(四)-基础最终篇
- Swift3.0从入门到放弃(一)
- Swift3.0从入门到放弃(二)
- Learning Swift 3.0 - 从精通到重新入门
- cocos2d-x 3.0学习——入门、创建菜单
- 《Java从入门到放弃》入门篇:运算符
- DWR3.0框架入门(1) —— 实现ajax
- swift入门-实现简单的登录界面
- 集成学习从放弃到再入门之 RF
- c++ 从入门到放弃
- Swift3.0- swift中的问号"?"和感叹号"!"语法
- Swift3.0语言教程字符串与文件的数据转换
- 十七 Swift3.0之 Switch用法
- 翻身的废鱼——论PHP从入门到放弃需要多久?1
- 《Java从入门到放弃》JavaSE篇:程序结构
- [C++ 从入门到放弃-02]C++STL之string
- Freemarker 从入门到放弃
- swift入门第三季(枚举,类,面向对象, 协议)
- 《Java从入门到放弃》JavaSE篇:练习——单身狗租赁系统(数组版)
- 入门到放弃之node系列Hello Word篇