美文网首页
Swift笔记

Swift笔记

作者: iSwifter | 来源:发表于2017-09-19 17:30 被阅读7次

    注意点

    • 1.无隐式转换 Float(param)

    通用

    关键字

    • 注意: 不可以在一个实体中定义访问级别更低的实体

    • 1.方法/属性
      * internal: 在本模块(项目/bundle/target)中都可以访问,系统默认的方法/属性权限
      * private: 只有在本类中才可以访问(extension亦不可访问,修饰方法是需要加@objc)
      * fileprivate: 在类所在文件中都可以访问
      * open: 可以跨模块访问(系统类可访问的属性/方法均为open)
      internal/fileprivate/private(set) 改变set访问权限

        * mutating: 修饰函数,表示该函数可以修改函数所属实例(属性)
        * subscript: 下标语法
      
        * inout: 输入输出参数,表示传入的参数本身会在函数内被修改,需要是&param指针类型,不能为let类型或者有默认值
      
        *convenience: 便利构造器
        
        @required: 必要的 required init(){ //构造器代码 }
      
    • 2.类型
      * 1.AnyObject > 任意class类型
      * 2.Any > 任意类型,包括函数类型
      * 3.as > 类型转换 A as B (switch A to B)

    • 3.文件级

    • SwiftCustomLogFunction

    func log<T>(message: T, file: String = #file, function: String = #function, line: Int = #line) {
        // setting: buildPhases - Swift complier-Custom Flags - Other Swift Flags - Debug -+ -D DEBUG
        #if DEBUG
        let fileName = (#file as NSString).lastPathComponent.split(separator: ".")
        print(">> \(message) << line:\(line) \(fileName) . \(function)")
        #endif
    }
    

    逻辑语句

    • 1.if > Swift所有条件表达式非0/nil即真的概念
    • 2.guard >== special if

    guard 条件表达式1 else {
    //条件1false 异常处理code
    return/break/continue/throw 关键字
    }
    (条件1ture) 执行语句
    guard 条件表达式2 else {
    //条件1true + 条件2false 异常处理
    return/break/contine/throw 关键字
    }
    (条件1true + 条件2true)执行语句
    ```

    • 3.switch
        * 1.判断条件可以使:Int \ Floaf \ String \ 区间范围
        * 2.关键字fallthrough (默认每个case 语句包含break)
        * 3.case 可以跟多个判断表达式 > case : 条件1, 条件2
    
    • 4.repeat while >== do wile inOC

    字符串

    • 1.拼接 > str1 + str2
    • 2.和标识符拼接 > \(param) : "name is \(name), age is \(age)"
    • 3.格式化 > String(format: arguments:) : String(format: "%02d:%02d", arguments:[min, second]);
    • 4.as NSString用法 > 常用于截取字符串场景: (urlString as NSString).substringToIndex(3)

    数组 (泛型集合,一般不存放不同类型元素)

    1. initializer

      * 1. let array = [1, 2, 3, 4, 5]
      * 2. var arrayM = [String]()
      
      
    2. 拼接 > array + array2(+ 仅限array1 与array2元素类型相同)

    3. 遍历 > for param in array[0..<2] { }

    字典

    • 1.initializer
        * 1. let dict = ["key1" : "value1", "key2" : "value2"]
        * 2. var dictM = Dictionary<String : anyObject>()
    
    • 2.增/改 删 查
    dictM[key] = value (无key为增, 有key为改)
    dictM.removeValue(forKey: "key") 删
    dictM["key"]
    for (key, value) in dictM {
        dictM[key] = value
    }
    

    元组

    • initializer
        * 1. let info = (name : "why", age : 19, height : 1.88) > info.name
        * 2. let info = ("why", 18, 1.88) > info.index >= info.1
        * 3. let (name, age, height) = ("why", 18, 1.89) > name
    

    可选类型

    • 1.initializer
        * 1. var name : String? = nil
        * 2. var name : Optional<String> = nil
        example: 
            let errorInfo = (errorCode: 404, errorMessage: "Not Found")
    
    • 2.强制解包可选绑定
        1. optionalName! > 注意:强制解包前一定要判断!= nil,否则崩溃
        2. if let optionalName = optionalName {
            执行optionalName用途 
        }
        相当于执行2步操作: 判断optionalName != nil, optionalName = optionalName!
        (当optionalName == nil,不执行{ }代码)
    

    函数

    • 1.intializer
        func 函数名(参数名: 参数类型, 参数名2: 参数类型) -> 返回值类型 {
            函数代码块
            return 返回值
        }
    
    • 2.使用注意
      * 1. 内部参数 & 外部参数 (参数别名可见范围区分,默认第一个参数为内部参数,其余为外部参数)
           参数1转换成外部参数 > 在参数1前再+别名
      * 2. 默认参数 
          func makeCoffee(coffeeName: String = "雀巢") -> String {}
          makeCoffee()
      * 3. 可变参数(参数数组)
          func calculator(params: Int...) -> Int {
              var result = 0
              for param in params {
                  result += param
              }
              return result
          }
      * 4. 指针参数
          func swapNum(inout m: Int, inout n: Int) {
              let temp = m
              m = n
              n = temp      
          }
          swapNum(m: &m, n: &n)
      * 5. 函数嵌套 
          func nestFunc() {
              func test() {
                  print("Test")
              }
              print"nestFunc"
              test()
          }       
      

    枚举

        注意: Swift枚举值可以是Int,Float,character,String,并且不手动提供枚举值,系统不会默认指定,如果需要指定枚举值,则必须在枚举后指定枚举值类型
        定义
        * 1. enum CompassPoint {
            case North
            case South
            case East
            case West
            }
        * 2. enum Planet: Int { // 可以枚举列举在一行
          case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
            } 
    

    结构体

    • 1.结构体是一个数据结构/值类型,在方法中是值传递, 类是指针传递
    • 2.定义格式: struct 结构体名称 { // 属性和方法 }
        struct Location {
            var x: Double
            var y: Double
            /// 构造函数必须确保素有成员变量都有被初始化,构造函数都不需要返回值
            // 系统默认会创建此种构造函数
            init(x: Double, y:Double) {
                self.x = x
                self.y = y
            }
            // 如果手动创建构造函数,就会覆盖默认构造函数,但可以手动再创建
            init(xyString: String) {
                let strs = xyString.components(separatedBy: ",")
                self.x = Double(strs.first ?? "0") ?? 0
                self.y = Double(strs.last! ?? "0") ?? 0
            }
        }
        /// 枚举拓展 - 可以拓展系统定义的结构体
        extension Location {
            mutating func move(x: Double, y: Double) { // 结构体可以扩充方法,修改成员变量的方法必须+ mutating
                self.x += x
                self.x += y
            }
        }
    

    class Student : NSObject {
        /***** 属性3种 *****/ // 初始化类的属性一般要赋值(值类型属性)或者指定可选类型(对象属性)
        /// 1.存储属性
        var englishScore: Double = 0.0
        var chineseScore: Double = 0.0
        /// 2.计算属性
        var averageScore: Double {
            return (englishScore + chineseScore) * 0.5
        }
        /// 3.类属性
        static var courseCount: Int = 0
        
        /***** 构造函数 *****/
        /// 1.重写构造函数
        override init() {
            super.init()
            // custom initCode
        }
        /// 2.自定义构造函数
        init(englishScore: Double, chineseScore: Double) {
            super.init() // 可省略,init默认会调用super.init()
            self.englishScore = englishScore
            self.chineseScore = chineseScore
        }
        /// 3.自定义构造函数withDictionary
    //    init(dictT: [String : AnyObject]) {
    //        if let score = dictT["chineseScore"] as? Double {
    //            chineseScore = score
    //        }
    //    }
        init(dict: [String : AnyObject]) {
            super.init()
           setValuesForKeys(dict)
        }
        override func setValue(_ value: Any?, forUndefinedKey key: String) {} // 必须重写防止崩溃
        
        /***** 类方法 *****/
        class func classFunc() {}
        
        /***** 属性监听器器 *****/
            var targetValue: Int = 0 {
            willSet { /* newValue */ }
            didSet { /* oldValue */ }
        }
        
        /****** 下标语法 *****/
        subscript (index: Int) -> Int { // 必须要有返回值 getter
            get {
                return index * index;
            }
            set { // newValue }
        }
        
        /***** 销毁 *****/
        deinit {
            相当于dealloc inOC
        }
    }
    
    Student.courseCount = 2
    let student = Student()
    student.englishScore = 78.0
    student.chineseScore = 80.0
    

    可选链

    • 1.从可选链中进行取值? > 返回值是可选类型,其中任意可选为nil,则整个可选链结果为nil let toy = person.dog?.toy?
    • 2.可选链获取目标进行赋值或调用方法 > 可选链任一部分为nil,不执行后续代码\方法 person.dog?.toy? = "Hello Kity"

    协议

    • 注意点
       0.协议作为类型,可以作为参数类型或返回值类型,集合元素类型
       1.协议协议遵守者可以是 class, enum, static
       2.代理类型的协议需要: class > 这样可以用执行修饰class的weak修饰可选类型的delegate
       3.optional特性来自OC,需要定义optional func 需要在protocol 和该方法前 + @objc
       4.协议定义属性:要求协议遵守者提供协议定义的属性,使用var定义,且只定义属性的名称、类型、读写属性
    
    • 用法

      • & 把两个协议结合成一个临时局部协议 : A & B
        func wishHappyBirthday(to celebrator: NamedProtocol & AgedProcotol) {
        print("Happy birthday, (celebrator.name), you're (celebrator.age)!")
        }
    • example

      @objc protocol SportProtocol {//协议遵守者可以是 class, enum, static
          func playBasketball()
          @objc optional func playFootball()
      }
      
      protocol purchaseDelegate: class {//
          func buy()
      }
      
      class person: SportProtocol {
          weak var deletage: purchaseDelegate?
          func goForeign() {
              deletage?.buy()
          }
          // SportProtocol implementation
          func playBasketball() { }
      }
      
    
    # 扩展 extension
    * 1.**定义**:为已有的类 结构体 枚举或者协议添加新功能
    * 2.**功能:**(类似 分类 inObjc)
    
    1.添加计算型 类/实例属性
    2.定义 实例/类方法,包括构造器
    3.定义下标
    4.定义和使用新的嵌套类型
    5.使一个已有类型符合某个协议
    
    * 3.**注意** 只能添加,不能重写已有功能
    
    # 闭包
    * 1.`格式: 类型 (参数列表) -> (返回值)`
    

    闭包的写法:
    类型:(形参列表)->(返回值)
    技巧:初学者定义闭包类型,直接写()->().再填充参数和返回值

    值:
    {
        (形参) -> 返回值类型 in
        // 执行代码
    }
    
    
    * 2.`闭包解决循环引用`
    
        ```
        方式1: == 简写方式2
        tools.loadData{[weak self] (jsonData) -> () in {
            self?.view.backgroundColor = UIColor.redColor
            }
        }
        方式2:
        weak var weakSelf = self
        tools.loadData { (jsonData) -> () in {
                weakSelf?.view.background = UIColor.redColor // 如果weakSelf != nil 执行语句
            }
        }
        ```
    * 3.`尾随闭包` > `当闭包是函数的最后一个参数,则该闭包为尾随闭包,尾随闭包函数可以将闭包提到()后,如果函数只有一个参数且为闭包,则可以省略参数列表外的()`
    
    # Error 
    * 1.定义
    
    func 方法(参数) throws返回值 {
        条件语句 {throw someError}
    }
    example:
        func age(age : Int) throws -> String {
            if age < 0 {
                throw AgeError.wrongAge // 错位定义成枚举类型, throw == return in 流程控制
            }
            return "OK"
        }
    
    
    * 2.处理 - 未被catch的error将层层传递
    
        ```
        1. do catch
         do {
            try throws类型的函数
         } catch 特定error {// 特定error
    
         } catch {// 所有error 
    
         }
         example:
        do {
            try student.age(age: -1)
        } catch {
            print("error")
        }
    
        2. try try? & try!(类似强制解包>有崩溃风险)
        try? > let str = stry? tudent.age(age: 10) 如果抛出错误,str = nil, 如果未抛出错误, str = 返回值
        ```
    
    # 指定清理操作 defer
    * `1. 用途` defer定义在即将离开当前代码块时执行的语句,离开当前代码块包括return , break, throw ERROR等
    * `2.注意:` defer语句中不能有流程控制转移,如break, return, throw ERROR等
    * `3.顺序` 多条fefer语句,反序执行,即最后的defer语句最先执行
    

    func processFile(filename: String) throws {
    if exists(filename) {
    let file = open(filename)
    defer {
    close(file)
    }
    while let line = try file.readline() { // 处理文件。
    }
    // close(file) 会在这里被调用,即作用域的最后。 }
    }

    
    # 类型转换 
    * 1.判断字:**is** > **if** *(something)* **is** *(anotherThing)* *return true/false*
    * 2.关键字:**as** > ** if let item = product as? Movie**
    
    # 元类型
    类、结构体、枚举类型的元类型: .Type / type(of: someInstance) > example: SomeClass.Type
    协议的元类型: .Protocol   > example: SomeProtocal.Protocol

    相关文章

      网友评论

          本文标题:Swift笔记

          本文链接:https://www.haomeiwen.com/subject/hjokdxtx.html