Swift 3.0学习总结

1.数据类型

1).元组swift

//元组赋值
let http404Error = (404,"Not Found");
//元组分解
let (statusCode,statusMessage) = http404Error;
//元组分解不须要的用_代替
let (justTheStatusCode,_) = http404Error;
//索引数字访问元组
print(http404Error.0,http404Error.1);
print(statusCode,statusMessage,justTheStatusCode);
//给元组内部元素命名,能够经过其访问元素
let http200Status = (statusCode:200,description:"OK");
print(http200Status.statusCode,http200Status.description);

 2).类型转换设计模式

swift没有隐式转换,数据类型须要转换到相同类型才能共同操做。数组

let m = 3;
let n = 2.14;
let result = Double(m)+n;

2.运算符

1).??ide

合并空值运算符 ( a ?? b )若是可选项 a  有值则展开,若是没有值,是 nil  ,则返回默认值 b 。表达式a 必须是一个可选类型。表达式 b  必须与 a  的储存类型相同。函数

a != nil ? a! : bpost

let defaultColorName = "red"
var userDefinedColorName: String? // defaults to nil
var colorNameToUse = userDefinedColorName ?? defaultColorName

print(colorNameToUse) //red

2).闭区间运算符( a...b )spa

3).半开区间运算符( a..<b 设计

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}
for index in 1..<5 {
    print("\(index) times 5 is \(index * 5)")
}

3.集合类型

1).遍历数组的key和value代理

使用 enumerated()方法来遍历数组。 enumerated()方法返回数组中每个元素的元组,
包含了这个元素的索引和值。你能够分解元组为临时的常量或者变量做为遍历的一部分:
for (index, value) in shoppingList.enumerated() {
    print("Item \(index + 1): \(value)")
}

2).有序遍历合集指针

Swift 的 Set类型是无序的。要以特定的顺序遍历合集的值,使用 sorted()方法,
它把合集的元素做为使用 < 运算符排序了的数组返回。
for genre in favoriteGenres.sorted() {
    print("\(genre)")
}
// Classical
// Hip hop
// Jazz

3).Dictionary的键值能够任意值

Set<Element>,Dictionary<Key, Value>,其中的Element,Key是用来做为字典键的值类型, 
Value就是字典为这些键储存的值的类型。
值类型是遵循Hashable协议.全部 Swift 的基础类型(好比 String, Int, Double, 和 Bool)
默认都是可哈希的,而且能够用于合集或者字典的键。
没有关联值的枚举成员值(如同枚举当中描述的那样)一样默承认哈希。

就像数组,你能够用初始化器语法来建立一个空 Dictionary:
var namesOfIntegers = [Int: String]()

2.逻辑语句

1).数字范围缩写

//半开半闭区间 0~9 => 0..<10
//闭区间 0~9 => 0...9

let source = 72;

switch source{
case 0..<60:
    print("不及格");
case 60...80:
    print("及格");
default:
    break;
}

2).if

    判断的条件必须只能是Bool类型,再也不存在非0即真

    新增guard,else语句中通常是return、break、continue和throw

func online(age:Int){
    
    guard age >= 18 else{
        print("未成年");
        return;
    }
    
    guard age <= 60 else{
        print("年龄太老");
        return;
    }
    
    guard age < 30 || age > 50 else{
        print("回家");
        return;
    }

    print("能够上网");
}

online(40);

3).switch

//switch 支持int、string、dobule
//1.swift switch默认case后补break,若是想要穿透使用fallthrough
let sex = 0;

switch sex {
case 0:
    print("人妖");
    fallthrough;
case 1:
    print("男");
case 2:
    print("女");
default:
    print("未知")
}

//2.数字范围缩写
//半开半闭区间 0~9 => 0..<10
//闭区间 0~9 => 0...9

let source = 72;

switch source{
case 0..<60:
    print("不及格");
case 60...80:
    print("及格");
default:
    break;
}

3.循环语句

1)for

//swift3只支持这种写法了
for i in 0..<10{
    print(i);
}

//不须要用到下标
for _ in 0...10{

2)while

var m = 0;
while m < 10 {
    m += 1;//swift3再也不支持m++这种写法了
    print(m);
}

repeat {
    m -= 1;
}while m > 0

4.函数

//内部参数 忽略参数名
func sum(num1:Int,_ num2:Int) ->Int{
    return num1+num2;
}
sum(2,5);

//可变函数
func sums(nums:Int...) ->Int{
    var total = 0;
    for n in nums{
        total += n;
    }
    return total;
}
sums(2,3,4,5,6);

//默认函数
func sex(s:String = "女"){
    print("sex:\(s)");
}
sex()

//指针函数
var m:Int = 3;
var n:Int = 2;

func swapNum(num1:inout Int,num2:inout Int){
    let temp = num1;
    num1 = num2;
    num2 = temp;
}

swapNum(&m, num2: &n);
print("m:\(m) n:\(n)");

5.枚举

//1.枚举类型的定义以及写法
enum MethodType1{
    case get
    case post
    case put
    case delete
}

enum MethodType2:String {
    case get="get"
    case post="post"
    case put="put"
    case delete="delete"
}

enum MethodType3 {
    case get,post,put,delete
}

//2.建立枚举具体的值
let type1 : MethodType1 = .get
let type2 = MethodType1.get
let type3 = MethodType1(rawValue:"put")
let str = type3?.rawValue

6.结构体

结构体是值类型,在方法中是值传递(对象是对象类型,在方法中是指针传递)

//1.定义结构体
struct Location {
    //成员属性
    var x : Double
    var y : Double
    
    //方法
    func test() {
        print("...")
    }
    
    //改变成员属性:涉及到改变成员属性的方法前需加上mutating
    mutating func moveH(distance : Double) {
        self.x += distance
    }
    
    //构造函数
    //1.默认下,会为结构体初始化一个带全部属性的构造函数
    //2.构造函数都是以init开头,而且构造函数不须要返回值
    //3.新构造的构造函数,必须保证因此的成员属性都被初始化
    init(x : Double, y: Double) {
        self.x = x
        self.y = y
    }
    
    //扩充构造函数
    init(xyStr : String) {
        let array = xyStr.components(separatedBy: ",")
        let item1 = array[0]
        let item2 = array[1]
        
        //Double(item1)是可选类型,有可能值为nil。若是强制解包let x = Double(item1)! 可能会崩溃
        /*
        if let x = Double(item1) {
            self.x = x
        }else{
            self.x = 0
        }
        if let y = Double(item2) {
            self.y = y
        }else{
            self.y = 0
        }*/
        
        //是上面的缩写,当值为nil的时候等于后值
        self.x = Double(item1) ?? 0
        self.y = Double(item2) ?? 0
    }
}


//2.建立结构体
let center = Location(x: 20, y: 30)
let moveH = Location(xyStr:"20,30")

7.类

1).类的定义

//1.OC定义类
//@interface Person : NSObject
//@end
//
//@impelment
//@end

//2.Swift定义类
class Person {
    
    //若是属性是值类型,则初始化为空值
    //若是属性是对象类型,则初始化为nil值(?的默认值是nil)
    
    //1.存储属性:用户存储实例的常量和变量
    var mathScore : Double = 0.0
    var chineseScore : Double = 0.0
    
    var view : UIView?
    
    //2.计算属性:经过某种方法计算得来结果的属性,就是计算属性
    var averageScore : Double {
        
        //简介写法
        //在类内部访问属性不须要加self.
        return (chineseScore + mathScore) * 0.5
        
        //完整写法
        /*
        set {
            
        }
        
        get {
            return (chineseScore + mathScore) * 0.5
        }
         */
        
    }
    
    //3.类属性 : 经过类名进行访问
    static var courseCount : Int = 0
    
    
    //OC中处理参数的方法 在swift中能够写成计算属性
    func getAverageScore() -> Double {
        return (chineseScore + mathScore) * 0.5
    }
}

//3.建立类的对象
let p = Person()
//类储存属性
p.view = UIView()
//类计算属性
p.mathScore = 90
p.chineseScore = 100
print(p.averageScore)
//类属性设置
Person.courseCount = 2

2.属性监听

class Person {
    
    var name : String = ""{
        
        //监听属性即将改变
        willSet(newValue){
            print(newValue) //打印新值 = "why"
            print(name)     //打印旧值 = "",属性还没改变
        }
        //监听属性已经发生改变
        didSet(oldValue){
            print(oldValue) //打印旧值 = ""
            print(name)     //打印新值 = "why",属性已经改变
        }
    }
}

let p = Person()
p.name = "why"

3.构造函数

/*
 使用KVC条件
   1>必须继承自NSObject
   2>必须在构造函数中,先调用super.init()
   3>调用setValuesForKeys
   4>若是担忧新建对象的时候,字典里含有的key不属于成员变量,则复写setValue forUndefinedKey
 */

class Person:NSObject {
    
    var name : String = ""
    var age  : Int = 0
    
    //若是须要扩展构造函数,须要先实现init,不然会被覆盖
    override init(){
        
    }
    
    init(dict : [String : Any]) {
        //swift开发中,若是在对象函数中,用到成员属性,那么self.能够省略
        //可是若是在函数中,有和成员属性重名的局部变量,那么self.不能省略
        
        //通用属性少的时候咱们能够这样写
        /*
         if let name = dict["name"] as? String {
         
         self.name = name;
         }
         if let age = dict["age"] as? Int {
         self.age = age;
         }
         */
        
        //属性多的时候咱们能够使用KVC赋值
        super.init()
        setValuesForKeys(dict)
    }
    
    override func setValue(_ value: Any?, forUndefinedKey key: String) {}
    
}

let p = Person()
let e = Person(dict:["name":"why","age":18,"height":1.88])
print(e.age,e.name)

4.析构函数

//和OC的delloc方法同样,监听对象的销毁
class Person:NSObject {
    
    var name : String = ""
    var age  : Int = 0
    
    //重写析构函数,监听对象的销毁
    deinit {
        print("delloc")
    }
}

var p : Person? = Person()
p = nil

5.循环引用

class Person {
    var book : Book?
    
    deinit {
        print("person -- deinit")
    }
}

class Book {
    
    /*
     OC中的标识弱引用
      __weak/__unsafe_unretianed(当对象释放了,指针依然指向旧地址,因此容易野指针)
     Swift中表示弱引用
      weak/unowned(野指针)
     */
    
    //unowned 不能修饰可选类型
//    unowned var person : Person = Person()
    weak var person : Person?
    
    deinit {
        print("book -- deinit")
    }
    
}

var person : Person? = Person()
var book : Book? = Book()

person!.book = book;
book!.person = person;

//若是不使用弱引用这个时候析构函数不打印
person = nil;
book = nil;

6.可选链使用

class Person {
    var name : String = ""
    var dog : Dog?
}
class Dog {
    var weight : Double = 0
    var toy : Toy?
}
class Toy {
    var price : Int = 0
    
    func flying(){
        print("fly")
    }
}

let p = Person()
p.name = "why"
let d = Dog()
d.weight = 100.5
let t = Toy()
t.price = 5

p.dog = d
d.toy = t

//可选链 .? 系统会自动判断可选类型是否有值
//可选链--取值
/*
 写法很是危险,尽可能不要强制解包
let dog = p.dog
let toy = dog!.toy
let price = toy!.price
 */

/*
 写法很繁杂
if let dog = p.dog {
    if let toy = dog.toy {
        let price = toy.price
    }
}
 */

let price = p.dog?.toy?.price

//可选链--赋值
p.dog?.toy?.price = 100

//可选链调用方法
p.dog?.toy?.flying()

8.协议

//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

//1.协议的定义,默认协议中的方法都是必须实现
protocol SportProtocol {
    func playBasketll()
}

//2.遵照协议,能够遵循多个协议,逗号个隔开
class Teacher : NSObject,SportProtocol{
    func playBasketll() {
        print("踢足球")
    }
}

//3.协议的代理设计模式
/*
 定义协议时,协议后面最好跟上:class,
由于delegate的属性避免循环引用,用week修饰,而week只能修饰类、属性。协议能够被类遵照,也能够被枚举、结构体
 */
protocol BuyTicketDelegate : class {
    func buyTicket()
}

class Person {
    
    //定义代理属性
    weak var delegate : BuyTicketDelegate?
    
    func gotoBeijing() {
        delegate?.buyTicket()
    }
}

class Stundnt : BuyTicketDelegate {

    internal func buyTicket() {
        print("买票")
    }
}

let p = Person()
let s = Stundnt()
p.delegate = s
s.buyTicket()


//4.协议的可选方法
//optional属于OC特性,若是协议中有可选方法,那么必须在protocol前加@objc
@objc protocol TestPro {
    @objc optional func test()
}

9.检查API的可用性

Swift 拥有内置的对 API 可用性的检查功能,它可以确保你不会悲剧地使用了对部属目标不可用的 API。

if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}
相关文章
相关标签/搜索