• Swift之基础知识


    Swift之基础知识

    • 出于对Swift3.0的学习,写下这篇基本语法的笔记。希望能帮助记忆 -0-
    • 这边提供Swift3.0中文教材,资源链接: https://pan.baidu.com/s/1c2GDBtI 密码: ea4i

    一. 第一个应用程序

    0. 小技巧:
    > 'option + cmd + /': 增加文档注释
    > 'color + 回车': 弹出颜色选择
    > '图片名 + 回车': 图像视图
    > '// MARK: - XXX': mark
    > '// TODO: XXX'和'// FIXME: XXX': 临时标注(一般用后者)
    
    1. 和OC的区别:
    1.1 类和对象
        OC:     '[[UIView alloc] initWithXXX: ];'
        Swift:  'UIView(XXX: )'
                'UIView()'
                
    1.2 类方法
        OC:     '[UIColor redColor]'
        Swift:  'UIColor.red()'
        2.0 :   'UIColor.redColor()'
        
    1.3 访问当前对象属性,可以不使用'self'
        建议都不用, 因为闭包(类似block)时需要使用'self'
        
    1.4 没有';', 默认一行一句代码就不出错
    
    1.5 枚举类型
        OC:     'UIButtonTypeContactAdd'
        Swift:  '.contactAdd'
        
    1.6 监听方法
        OC:     '@selector'
        Swift:  '#selector',有参数不需要加':'
        2.0:    直接使用"",有参数需要加':'
    

    二. 变量与常量

    1.变量: 值能被修改, var修饰 
      常量: 值不能被修改, let修饰
    2.自动推导: 变量/常量的类型会根据右侧的代码执行结果,推导对应的类型(option + click查看)
    3.注意点:
        > 在任何不同类型的数据之间, 不允许直接运算
        > 不存在基本数据类型, 都是结构体
    4.optional可选项(等价于:类型+?)
        4.1 可以有值, 可以为nil不是任何数据类型,不能参与计算
        4.2 计算要用'!'强制解包, 如果有nil, 则直接报错:unexpectedly found nil wghile unwrapping an Optional value
        4.3 let的可选值没有默认值
            var的可选值默认为nil
        4.4 空合运算符( a ?? b )将对可选类型 a 进行空判断:如果a为nil,则执行b,否则执行a
    

    三. 分支语句

    1. if语句

    1.1 注意点
        1) 条件不需要'()'
        2) 语句必须有'{}'
    

    2. ??可选项的判断

    2.1 空合运算符( a ?? b )将对可选类型 a 进行空判断:如果a为nil,则执行b,否则执行a
    2.1 优先级比较低, 使用时最好加(), 例子如下:
        let aName: String? = "老王"
        print((aName ?? "") + "hello") // 打印:老王hello
        print(aName ?? "" + "hello")// 打印:老王
    

    3. if let & if var

    let aDog: String? = "laowang"
    let aAge: Int? = 10
    // 3.1 判断对象的值是否为nil, {}内一定有值,可以直接使用不需要解包
    // 3.2 if var连用, {}可以对值进行修改
    if var name = aDog,
        let age = aAge {
        // 进入分支后,name和age一定有值,不需要解包
        // name和age的作用于仅在{}中
        name = "laoxiao"
        print(name+String(age))
    }else {
        print("name或age有一个为nil")
    }
    

    3. guard let

    // 3.1. guard let 和 if let刚好相反
    // 3.2. guard let 守护一定有值,如果没有直接返回
    let aDog: String? = "laowang"
    let aAge: Int? = 10
    
    guard let name = aDog,
        let age = aAge else {
        print("name或age为nil")
        return
    }
    // 代码执行到这, name和age一定有值
    // 通常判断是否有值之后, 会做具体的逻辑实现,通常代码多
    // 如果用if let会多一层分支,guard是降低分支层次的办法
    print(name+String(age))
    

    4. switch

    // 1.值可以是任何类型
    // 2.作用域仅在 case 内部
    // 3.不需要 break
    // 4.如果要多值,使用','
    // 5.每一个 case 都要有代码
    let name = "nick"
    
    switch name {
    case "nick":
        let age = 18
        print("one  (age)")
    case "fil":
        print("two")
    case "Davi":
        print("three")
    case "": break  //相当于有一行代码
    case "tom","ningcol":
        print("tomAndNingcol")
    default:
        print("other")
    }
    

    5. for循环

    // 5.1 普通for循环: ..< 左闭右开; ...闭区间
    for i in 0..<10 {
        print(i)
    }
    // 5.2 使用 "_" 忽略不关心的值
    for _ in 0..<5{
        print("hello")
    }
    // 5.3 递增(步数为2)
    for i in stride(from: 0, to: 12, by: 2) {
        print(i)
    }
    // 5.4 递减
    for i in stride(from: 12, to: 0, by: -2) {
        print(i)
    }
    // 5.5 反序循环
    let range = 0...10
    for i in range.reversed(){
        print(i)
    }
    
    /***************************while循环*************************/
    print("----while循环----")
    var n = 2
    while n < 100 {
        n=n * 2
    }
    print(n)
    
    /***************************epeat-while循环*************************/
    //它和 while 的区别是在判断循环条件之前,先执行一次循环的代码块。然后重复循环直到条件为 false
    var m = 2
    repeat {
        m = m * 2
    } while m < 100
    print(m)
    

    四. 字符串

    1. String 结构体,效率比对象高,一般推荐使用,支持遍历
    2. NSString 继承NSObject

    1. 遍历

    for c in str.characters {
        print(c)
    }
    

    2. 长度

    // 2.1 放回指定编码对应的字节数
    // UTF8 的编码(0-4个), 每个汉字是3个字节
    str.lengthOfBytes(using: .utf8)
    // 2.2 返回字符个数(最常用)
    str.character.count
    // 2.3 使用NSString中转实现2.2
    let ocStr = str as NSString
    ocStr.length
    

    3. 拼接

    // 1."(变量或常量)"
    // 但是要注意可选项, 用??语句
    let name:String? = "老王"
    let age = 80
    let location = "隔壁"
    print(location + (name ?? "a") + String(age) + "岁")// "隔壁老王80岁"
    print("(location)(name)(age)岁")// "隔壁Optional("老王")80岁"
    let rect = CGRect(x: 0, y: 0,  100, height: 100)
    print("(rect)")// "(0.0, 0.0, 100.0, 100.0)"
    
    // 2.格式化字符串
    let h = 13
    let m = 5
    let s = 9
    let timeStr = String(format: "%02d:%02d:%02d", arguments: [h,m,s])// "13:05:09"
    let timeStr1 = String(format: "%02d:%02d:%02d", h,m,s)// "13:05:09"
    

    4. 子串

    一般使用NSString作为中转, 因为Swift取子串一直在优化, swift方法忽略

    五. 集合

    1. 数组

    和OC一样, 但是没有'@'

    1.1 定义和初始化

    let array1 = ["zhangsan","lisi"]
    let array2 = [1,2,3,4,5]
    
    var array3:[Int] // 定义一个数组(没有初始化)
    array3 = [Int]() //初始化
    
    //声明空数组,(必须初始化)
    let array4 = [String]()  // 等价上面两行代码
    
    // Any任意对象
    let array5:[Any] = ["zhangsan","lisi",20]
    
    var arr3 = [Double](repeating: 0.0, count: 3) //[0.0, 0.0, 0.0]
    var arr4 = Array(repeating: 3.0, count: 3)  //[3.0, 3.0, 3.0]
    

    1.2 遍历

    // 1.内容遍历
    for name in array1{
        print(name)
    }
    // 2.下标遍历
    for i in 0..<array2.count{
        print(array2[i])
    }
    // 3.enum block遍历, 同时遍历下标和内容
    for e in array2.enumerated(){
        print(e)
        print("元组 (e.offset) (e.element)")
    }
    // 4.同时遍历下标和内容 2
    for (n,s) in array2.enumerated(){
        print("(n) (s)")
    }
    // 4.反序遍历
    for a in array2.reversed(){
        print(a)
    }
    

    1.3 增删改

    // 增加
    arr.append("haha")
    
    // 修改
    arr[0] = "Tom"
    
    // 删除
    arr.removeFirst()
    arr.remove(at: 2)
    
    // 删除全部并保留空间
    arr.removeAll(keepingCapacity: true)
    print(arr.capacity)  //数组容量
    
    /************容量*************/
    // 容量每次都会在原来基础上 * 2
    print("初始容量 (array3.capacity)")
    for i in 0..<8{
        array3.append(i)
        print("(array3),容量:(array3.capacity)")
    }
    

    1.4 合并

    // 直接相加
    var arr = ["haha", "nihao", "hello"]
    let arr1 = ["Evi","Tank"]
    arr += arr1
    
    // 注意点:类型必须一致
    var arr1:[NSObject] = ["Evi" as NSObject,"Tank" as NSObject]
    let arr2:[NSObject] = [1 as NSObject,2 as NSObject]
    arr1 += arr2;
    

    2. 字典

    OC中使用{}, swift中使用[]

    2.1 定义和初始化

    let dict1 = ["name":"lisi","age":"18"]
    // 不同类型必须指明为 any
    var dict2:[String:Any] = ["name":"lisi","age":18]
    
    // 字典数组
    let array = [
        ["name":"lisi","age":"18"],
        ["name":"wangwu","age":8]
    ]
    let array1:[[String:Any]] = [
        ["name":"lisi","age":"18"],
        ["name":"wangwu","age":8]
    ]
    

    2.2 增删改

    // 增加
    dict2["sex"] = "man"
    // 修改(通过key来取值,key不存在就是新增)
    dict2["name"] = "zhangsan"
    // 删除(直接给key进行删除)
    dict2.removeValue(forKey: "age")
    

    2.3 遍历

    for e in dict2{
        //e 为元组
        print("字典遍历:(e)  e.key:(e.key)  value:(e.value)")
    }
    for (key,value) in dict2{
        print("key:(key), value:(value)")
    }
    

    2.4 合并

    var dict3:[String:Any] = ["name":"zhangsan","age":18,"sex":"man"]
    let dict4:[String:Any] = ["name":"haha","height":50]
    // 如果key存在修改  不存在会增加
    for e in dict4{
        dict3[e.key] = dict4[e.key]
    }
    print("合并dict:" + String(format: "%@", dict3))
    

    六. 函数

    1. 定义

    // 格式: 函数名(形参列表) -> 返回值类型
    func sum(x: Int ,y: Int) -> Int{
        return x + y
    }
    
    /**
        1.外部参数是在形参前加一个名字
        2.外部参赛不影响内部细节
        3.外部参数让调用更加直观
    */
    func sum(numX x: Int ,numY y: Int) -> Int{
        return x + y
    }
    print(sum(numX: 30, numY: 40))
    
    // 外部参数使用 "_" 会忽略形参
    func sum(_ x: Int ,_ y: Int) -> Int{
        return x + y
    }
    print(sum(40, 50))
    
    // 不指定参数的值就为默认值
    func sum1(x: Int = 1 ,y: Int = 2) -> Int{
        return x + y
    }
    print(sum1())
    print(sum1(x: 10, y: 10))
    print(sum1(x: 20))
    print(sum1(y: 20))
    

    2. 闭包

    2.1 定义

    提前准备好的代码,在需要的时候执行,类似于oc中的block

    /**
        1.参数,返回值,实现代码都是写在 {} 中
        2.必须以 "in" 关键字分隔定义和实现
        3.格式: (形参列表 -> 返回值类型 in) 实现代码
    */
    // 无返回值,有参数
    let demo1 = { (x: Int) -> () in
        print(x)
    }
    demo1(50)
    
    // 有返回值,有参数
    let demo2 = {
        (x: Int) -> (Int) in
        return 40 + x
    }
    print(demo2(40))
    

    2.2 实际应用

    同OC中的 Block 一样

    2.3 循环引用

    • 类似于oc一样,用weak var weakSelf = self // 注意只能用var来创建
    • 在闭包中加入[weak self] in,此时self为可选类型
    • 在闭包中加入[unknow self] in,不推荐,此时self不是可选类型,当self对象释放了在调用会出现奔溃。

    2.4 尾随闭包

    当一个函数的最后一个参数是闭包时,可以写成尾随闭包格式,了解就好。

    // 尾随GCD闭包
    DispatchQueue.global().async {
    }
    
    // 普通GCD闭包
    DispatchQueue.global().async(execute: {
    })
    
  • 相关阅读:
    第七周-学习进度条
    《梦断代码》阅读笔记01
    第六周-学习进度条
    构建之法阅读笔记03
    结对项目开发(石家庄地铁乘车系统)
    第五周-学习进度条
    第四周-学习进度条
    HDU--1272 小希的迷宫(并查集判环与联通)
    HDU--1856 More is better(简单带权并查集)
    HDU--3635 带权并查集
  • 原文地址:https://www.cnblogs.com/LongLJ/p/6108759.html
Copyright © 2020-2023  润新知