swift学习笔记《2》-swift语法

1.常量变量

  • let var

2.数据类型

  • 整型,浮点型,对象类型,结构体类型(swift中大部分类改为了结构体)
  • 整型
  • Int8 有符号8位整型

  • Int16 有符号16位整型

  • Int 32 有符号32位整型

  • Int 64 有符号64位整型

  • Int 与平台有关,默认相当于OC中NSInteger

  • UInt8 无符号8位整型

  • UInt16,UInt32,UInt64

  • 浮点型

  • Float 32位浮点型 Double 64位浮点型

  • 基本运算

  • 相同运算符之间才能参与运算,因为swift中没有隐式转换

3.逻辑分支

  • if switch 三目运算符 等判断语句

  • guard运算符(守护)

  • 当条件表达式位true的时候跳过else语句,继续向下执行

  • 当条件表达式为false的时候进入else语句中,break,continue,return,throw等跳出

    guard 条件表达式 else {
        // 条换语句
        break
    }
    语句组
    
    复制代码
  • switch语句

  • switch 的case之后不必须加break case不在只是Int,可以是浮点,字符串,区间(0..<10,0...10)

  • 一个case 可以判断多个值,用,隔开

4.循环

  • for循环
  • 开区间(0..<10),闭区间(0...10)
  • for循环打印字典时可以使用元组
  • whiledo-while 循环
  • 使用repeat while循环代替do-while循环
  • i++已经被弃用,使用i=i+1;

5.字符串

  • String 是结构体,性能比NSString 高

  • String的长度,astring.characters.count 字符串长度

  • str1 + str2 两个字符串相加

  • 字符串的格式化输出

    String(format: "%02d:%02d", arguments: [min, second])
    复制代码
  • 字符串的截取 暂时先转为NSString 进行截取

    let myStr = "www.520it.com"
    var subStr = (myStr as NSString).substringFromIndex(4)
    subStr = (myStr as NSString).substringToIndex(3)
    subStr = (myStr as NSString).substringWithRange(NSRange(location: 4, length: 5))
    复制代码

6数组

  • Array 一个范型数组

  • 数组声明方法

    var stuArray1:Array<String>
    var stuArray2: [String]
    复制代码
  • 数组的 增- 删- 改- 查

    // 添加数据
    array.append("yz")
    // 删除元素
    array.removeFirst()
    // 修改元素
    array[0] = "why"
    // 取值
    array[1]
    复制代码
  • 数组的合并 同类型的两个数组可以直接相加

    // 数组合并
    // 注意:只有相同类型的数组才能合并
    var array = ["why", "lmj","lnj"]
    var array1 = ["yz", "wsz"]
    var array2 = array + array1;
    
    // 不建议一个数组中存放多种类型的数据
    var array3 = [2, 3, "why"]
    var array4 = ["yz", 23]
    array3 + array4
    
    复制代码

7.字典

  • Dictionary 是个范型集合

  • 声明方式

    var dict1: Dictionary<Int, String>
    var dict2: [Int: String]
    复制代码
  • 字典的增 -删- 改- 查

    // 添加数据
    dict["height"] = 1.88
    dict["weight"] = 70.0
    // 删除字段
    dict.removeValueForKey("height")
    // 修改字典
    dict["name"] = "lmj"
    // 查询字典
    dict["name"]
    复制代码
  • 字典的遍历 使用元组

  • 字典的合并

    // 字典的合并
    var dict1 = ["name" : "yz", "age" : 20]
    var dict2 = ["height" : 1.87, "phoneNum" : "+86 110"]
    // 字典不可以相加合并
    for (key, value) in dict1 {
        dict2[key] = value
    }
    
    复制代码

8.元组

  • 是swift中特有的定义一组数据,类型可相同可不相同
    // 元组:HTTP错误
    // let array = [404, "Not Found"]
    // 写法一:
    let error = (404, "Not Found")
    print(error.0)
    print(error.1)
    
    // 写法二:
    
    let error = (errorCode : 404, errorInfo : "Not Found")
    print(error.errorCode)
    print(error.errorInfo)
    
    // 写法三:
    let (errorCode, errorIno) = (404, "Not Found")
    print(errorCode)
    print(errorIno)
    复制代码

9.可选类型

  • 可选类型的取值,有值或者是空值

  • 可选类型的使用

  • 使用场景

    // 该方式利用类型推导
    let url = NSURL(string: "www.520it.com")
    // 通过url来创建request对象:在使用可选类型前要先进行判断是否有值
    // 该语法成为可选绑定(如果url有值就解包赋值给tempURL,并且执行{})
    if let tempUrl = url {
        let request = NSURLRequest(URL: tempUrl)
    }
    复制代码

10.函数

  • 函数的格式

    func 函数名(参数列表) -> 返回值类型 {
        代码块
        return 返回值
    }
    
    func 函数名(参数1:参数1类型,参数2:参数2类型) -> 返回值类型 {
        代码块
        return 返回值
    }
    
    复制代码
  • 函数 外部参数和内部参数

  • 变量名前加标签就是外部参数

  • 方法重写 子类重新调用父类方法是重写,override

  • 方法重载 方法名相同但是参数不同,称为方法重载

    // num1和a是外部参数的名称
    func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int {
        return num1 * num2 * num3
    }
    
    var result1 = ride(num1: 20, a: 4, b: 5)
    // 方法的重载:方法名称相同,但是参数不同,可以称之为方法的重载(了解)
    func ride(num1: Int, _ num2 :Int) -> Int {
        return num1 * num2
    }
    var result2 = ride(20, 20)
    复制代码
  • 函数的默认参数

  • 不传的话有个默认值

    func makecoffee(type :String = "卡布奇诺") -> String {
        return "制作一杯\(type)咖啡。"
    }
    复制代码
  • 可变参数

  • 可以接受不确定数量的输入类型参数,但必须是相同类型,在参数类型后面拼接**...** 来实现

    func sum(numbers:Double...) -> Double {
        var total: Double = 0
        for number in numbers {
            total += number
        }
        return total
    }
    sum(100.0, 20, 30)
    sum(30, 80)
    复制代码
  • 函数引用类型-指针传递

  • 默认是值传递,不改变外部变量的值,如果想改变,需要传地址

  • 传入的地址必须是变量

  • swift提供inout 关键字实现

11.swift中类的使用

  • 定义类的时候可以没有父类,需要父类的话大多可以使用NSObject 作为父类,非OC的NSObject

  • 类的属性 分为 储值属性,算值属性,类属性

  • 储值属性

  • 计算型属性 不存储实际值,提供getter 和可选的setter间接获取或设置其他属性,

    • 一般只提供getter 方法,如果只实现了getter 方法,则为只读属性,可以省略get{},直接return
  • 类属性 所有的类和类的实例都有一份类属性,如果在某一处更新后,该类属性就会被修改

  • 类属性使用static 关键字修改,

  • 监听属性的修改

  • 在oc中使用set 方法监听

  • 在swift中,使用属性观察者监听和相应属性值的变化

  • 使用属性的will set 方法监测新值,在didset中监测旧值

  • willSet (new){ } didSet(old){}

  • 在didset中生成计算型属性的值

  • didSet 属性直接赋值不会调用didSet方法,而是在初始化之后再赋值才能调用

    var expires_in: NSTimeInterval = 0 {
        didSet {
            expiresDate = NSDate(timeIntervalSinceNow: expires_in)
        }
    }
    复制代码

12.类的构造函数

  • 构造函数的基本使用

  • 类的属性必须有值,如果不是在初始化的时候复制,在构造方法中给类属性赋值,

    class Person: NSObject {
        var name : String
        var age : Int
        // 重写了NSObject(父类)的构造方法
        override init() {
            name = ""
            age = 0
        }
    }
    
    // 创建一个Person对象
    let p = Person()
    复制代码
  • 初始化的时候给属性赋值

  • 如果在自定义对象的时候给属性赋值,自定义init方法,会覆盖init方法,不会有默认的初始化方法

    class Person: NSObject {
        var name : String
        var age : Int
        // 自定义构造函数,会覆盖init()函数
        init(name : String, age : Int) {
            self.name = name
            self.age = age
        }
    }
    // 创建一个Person对象
    let p = Person(name: "why", age: 18)
    复制代码

13 字典转模型 (初始化时传入字典)

  • 字典取值是NSObject 是任意类型
  • 可以通过as转换之后再赋值,不同类型不能直接赋值
    class Person: NSObject {
        var name : String
        var age : Int
        // 自定义构造函数,会覆盖init()函数
        init(dict : [String : NSObject]) {
            name = dict["name"] as! String
            age = dict["age"] as! Int
        }
    }
    
    // 创建一个Person对象
    let dict = ["name" : "why", "age" : 18]
    let p = Person(dict: dict)
    复制代码

14 字典转模型 (KVC 转化)

  • kvc 不能保证全部复制,所以属性要有默认值,基本数据类型默认值是0,对象结构体定义为可选即可
    class Person: NSObject {
        // 结构体或者类的类型,必须是可选类型.因为不能保证一定会赋值
        var name : String?
        // 基本数据类型不能是可选类型,否则KVC无法转化
        var age : Int = 0
        
        // 自定义构造函数,会覆盖init()函数
        init(dict : [String : NSObject]) {
            // 必须先初始化对象
            super.init()
            // 调用对象的KVC方法字典转模型
            setValuesForKeysWithDictionary(dict)
        }
    }
    // 创建一个Person对象
    let dict = ["name" : "why", "age" : 18]
    let p = Person(dict: dict)
    复制代码

15闭包的介绍

  • 闭包就是匿名函数

  • block 的写法

    类型:
    返回值(^block的名称)(block的参数列表)
    ------
    
    值:
    ^(参数列表){
        // 执行的代码
    }
    复制代码
  • swift的写法

  • 定义网络请求的类

    func loadRequest(callBack:()->()){
        callBack()
    }
    复制代码
  • 使用闭包

    httpTool.loadRequest( { ( )->( ) in 
        tableView.reloadData
    })
    复制代码
  • 闭包总结

    闭包的写法:
    类型:  (型参列表)->( 返回值 )
    
    值:
    {  ( 型参列表 ) -> 返回值类型 in  
    
    // 执行代码
    }
    
    复制代码
  • 尾随闭包

    • 如果闭包没有参数没有返回值,( ) -> ( ) in可以省略

    • 如果闭包是作为函数的最后一个参数,则可以将闭包写在()后面

    • 如果函数只有一个参数,且最后一个参数是闭包,那么()也可以不写,直接在方法名后面拼接{}

      省略前
      httpTool.loadRequest({ ( ) -> ( ) in 
          print(完全不省略)
      })
      
      省略1
      httpTool.loadRequest({
          print(省略括号 in)
      })
      
      省略2
      httpTool.loadRequest( ){ 
          print(小括号前置)
      }
      
      省略3
      httpTool.loadRequest{ 
          print(终结版尾随闭包)
      }
      复制代码

16.闭包的循环引用

  • deinit{}实现deinit 函数,检测一个对象是否销毁

  • swift 循环引用的三种方式

    • 使用weak,使用【weak self】,使用unowned 关键字
  • 使用weak 关键字对控制器持有,weakself是可选类型,使用时强行解包,因为一定有值

    weak var weakSelf = self
    httpTool.loadData {
        print("加载数据完成,更新界面:", NSThread.currentThread())
        weakSelf!.view.backgroundColor = UIColor.redColor()
    }
    
    复制代码
  • 使用 【weak self】 【weak self 】写在闭包中,在闭包中使用的self 都是weak的

    httpTool.loadData {[weak self] () -> () in
        print("加载数据完成,更新界面:", NSThread.currentThread())
        self!.view.backgroundColor = UIColor.redColor()
    }
    复制代码
  • unowned 类似oc的unretain ,即使原来引用的对象释放了,也会对释放的对象,持有一个无效的引用,不是可选的,不可能指向nil

    httpTool.loadData {[unowned self] () -> () in
        print("加载数据完成,更新界面:", NSThread.currentThread())
        self.view.backgroundColor = UIColor.redColor()
    }
    复制代码

17.懒加载

  • 希望所有的对象,只有加载的时候才能加入到内存中,

  • lazy 关键字,是专门修饰懒加载属性的

  • 格式

    lazy var 变量名 = { 创建变量代码 }()
    复制代码
  • 使用

    // 懒加载的本质是,在第一次使用的时候执行闭包,将闭包的返回值赋值给属性
    // lazy的作用是只会赋值一次
    lazy var array : [String] = {
        () -> [String] in
        return ["why", "lmj", "lnj"]
    }()
    复制代码

18.便利构造函数

  • convenience : 便利,使用convenience修饰的构造函数叫做便利构造函数

  • 便利构造函数通常用在对系统的类进行构造函数的扩充时使用

  • 便利构造函数的特点

  • 便利构造函数,一般写在extension中

  • 便利构造函数,在init前面添加convenience 关键字

  • 在便利构造器中需要明确调用self.init(), 而且是先调用。

  • 在继承中,重写父类的方法中,初始化自己的方法中,先初始化自己的属性,之后调用父类的super.init()

19 #Selector() 事件监听

  • 事件监听本质发送消息.但是发送消息是OC的特性

  • 将方法包装成@SEL --> 类中查找方法列表 --> 根据@SEL找到imp指针(函数指针) --> 执行函数

  • 如果swift中将一个函数声明称private,那么该函数不会被添加到方法列表中

  • 如果在private前面加上@objc,那么该方法依然会被添加到方法列表中

20.类型转换

  • 类型转换在 Swift 中使用isas操作符实现 ,你也可以用它来检查一个类型是否实现了某个协议,就像在检验协议的一致性部分讲述的一样。

  • 定一个类MediaItem,name 属性,init(name:) 方法

  • 其2个子类MovieSong

  • 检查类型

  • is判断是一个实例,是否属于特定子类 if item is Movie

  • 向下转型

  • 使用子类特有的属性和方法,使用as 转化为子类 as?和as!

21.Any 和 AnyObject 的类型转换

  • Any 表示任何类型,包括函数类型
  • AnyObject表示任何类型的实例
    for thing in things {
        switch thing {
        case 0 as Int:
            print("zero as an Int")
        case 0 as Double:
            print("zero as a Double")
        case let someInt as Int:
            print("an integer value of \(someInt)")
        case let someDouble as Double where someDouble > 0:
            print("a positive double value of \(someDouble)")
        case is Double:
            print("some other double value that I don't want to print")
        case let someString as String:
            print("a string value of \"\(someString)\"")
        case let (x, y) as (Double, Double):
            print("an (x, y) point at \(x), \(y)")
        case let movie as Movie:
            print("a movie called '\(movie.name)', dir. \(movie.director)")
        case let stringConverter as String -> String:
            print(stringConverter("Michael"))
        default:
            print("something else")
        }
    }
    
    // zero as an Int
    // zero as a Double
    // an integer value of 42
    // a positive double value of 3.14159
    // a string value of "hello"
    // an (x, y) point at 3.0, 5.0
    // a movie called 'Ghostbusters', dir. Ivan Reitman
    // Hello, Michael
    复制代码

22.在一个类型中嵌套另外一个类型

  • BlackjackCard(二十一点),结构体中,嵌套Suit,Rank 两个枚举

    struct BlackjackCard {
    
        // 嵌套的 Suit 枚举
        enum Suit: Character {
            case Spades = "♠",
                Hearts = "♡", 
                Diamonds = "♢", 
                Clubs = "♣"
        }
    
        // 嵌套的 Rank 枚举
        enum Rank: Int {
            case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
            case Jack, Queen, King, Ace
            struct Values {
                let first: Int, second: Int?
            }
    
            var values: Values {
                switch self {
                    case .Ace:
                        return Values(first: 1, second: 11)
                    case .Jack, .Queen, .King:
                        return Values(first: 10, second: nil)
                    default:
                        return Values(first: self.rawValue, second: nil)
                }
            }
        }
    
        // BlackjackCard 的属性和方法
        let rank: Rank, suit: Suit
        var description: String {
            var output = "suit is \(suit.rawValue),"
            output += " value is \(rank.values.first)"
            if let second = rank.values.second {
                output += " or \(second)"
            }
            return output
        }
    }
    复制代码
  • 初始化 let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)

  • 使用:let heartsSymbol = BlackjackCard.Suit.Hearts.rawValue

转载于:https://juejin.im/post/5b8f9b98e51d450e7c0d1a62

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值