zoukankan      html  css  js  c++  java
  • Swift初体验

    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("初始化")
        }
      }
     
  • 相关阅读:
    vue在new的时候做了什么???
    vue中关于this的指向
    jquery 的本地存储 localStorage
    解读vue实例的双向绑定源码
    node修改数据遇到的坑
    node.js邮箱验证码
    webpack基础配置
    获取时间差。
    js获取时间方法
    node的buffer转换为字符串
  • 原文地址:https://www.cnblogs.com/YRFios/p/4984645.html
Copyright © 2011-2022 走看看