Swift笔记

注意点

  • 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 初见swift 打印‘hello world' print("hello world"); 教程 类型 基础类型:...
    PanPan1127阅读 851评论 0 2
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 3,826评论 0 6
  • 渲染: 1 当前屏幕渲染:在GPU的当前屏幕缓冲区中进行的渲染 2 离屏渲染:在GPU当前屏幕缓冲区外另建缓冲区渲...
    adrian920阅读 367评论 0 0
  • 1、随机数 不需要随机数种子 arc4random()%N + begin:产生begin~begin+N的随机数...
    我是小胡胡分胡阅读 4,136评论 0 2
  • 1、范型范型所解决的问题 函数、方法、类型:类,结构体,枚举,元组类型,协议参数,返回值,成员函数参数,成员属性类...
    我是小胡胡分胡阅读 816评论 0 1