Swift

作者: 简简简简简书 | 来源:发表于2016-06-06 22:52 被阅读138次

    Swift

    常量和变量

    • var 定义变量,设置之后可以修改
    • let 定义常量,设置之后不可以修改
    • 语句末尾不用使用 ;
    • 在 Swift 中使用 print() 替代 OC 中的 NSLog,print 的性能更好
    • let定义常量,该常量的内存地址不允许修改,但是可以修改其内部的属性
    • 常量&变量的使用原则:初学的时候,尽量先用 let,只有需要变的时候,再用 var,能够更加安全
    • 初次接触 Swift 中会因为简单的 var let 误以为 Swift 中的类型非常松,其实所有变量的准确类型都是在赋值的同时自动推导的
    • Swift 是对类型要求非常严格的一门语言,一个值永远不会被自动转换成其他类型,如果要转换,必须显示转换
    //常量不可以改变
    let number = 10;
    //变量
    var number1 = 10;
    number1 = 20;
    //Swift可以自行做类型推断
    print(number)
    
    
    
    //定义变量(如果指定类型,一定要显性的)
    var name:String = "shkljsjd"
    var age:Int = 12;
    var height:Float = 180.5
    var 体重:Double = 12.2
    var gender:Bool = true
    var sex: Character = "m"
    var telephone = "123456789"
    
    
    //类型转换
    let 整型体重 = Int(height)
    print(整型体重)
    var 整型电话 = Int(telephone)!
    print(整型电话)
    

    字符串

    使用String的原因

    • String 是一个结构体,性能更高
      • String 目前具有了绝大多数 NSString 的功能
      • String 支持直接遍历
    • NSString 是一个 OC 对象,性能略差
    • Swift 提供了 StringNSString 之间的无缝转换
    • 在Swift中绝大多数的情况下,推荐使用 String 类型
    //遍历字符串
    let str = "qwerasdf"
    for s in str {
        print(s)
    }
    
    //获取字符串的长度
    print(str2.characters.count)
    
    // 字符串快速拼接
    let str1 = "zhangsan"
    let str2 = "lisi"
    let i = 10
    print(str1 + str2)//可以理解成数组
    print("\(str1) \(str2) \(i)")//这里可以使用\(变量名)的方式快速拼接字符串
    
    
    
    //字符串的拼接
    //这里是swift中的字符串(非常非常费劲)的拼接方法
    let str: String = "zhangwu"
    var subStr = str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex))
    str.insert("1", atIndex: str2.startIndex.advancedBy(3))
    //所以一把建议把swift里面的字符串转换成NSString进行拼接(删除方法同理)
    let str3: NSString = "zhangsanwangwu"
    print(str3.substringWithRange(NSMakeRange(0, 3)))
    
    
    
    
    // 格式化字符串(这里提供了一种和OC中的stringWithFormat一样的方法,需要注意的后面的arguments是一个数组,即使一个变量也要放入数组中)
    for _ in 0...10 {
        let str = String(format: "zhangsan - %04d", arguments: [arc4random_uniform(100)])
        print(str)
    }
    

    数组,字典,元组

    数组

    • 如果定义数组时指定了保存对象的类型,择不能向数组中添加其他类型的内容
    • let 定义的数组是不可变的
    • var 定义的数组是可变的
    // 数组中保存的都是字符串
    let arr = ["zhangsan", "lisi"]
    
    // 数组中保存的是 NSObject
    let arr1 = ["zhangsan", 1]
    
    // 添加元素
    array.append("lisi")
    
    //更新
    array[0] = "zhangwu"
    
    // 删除元素
    array.removeAtIndex(1)
    
    // 拼接数组
    var array2 = [String]()
    array2.append("1")
    array2.append("2")
    array += array2
    
    

    字典

    // 定义并实例化字典(这种类型是开发中常用的类型)
    var dict = [String: AnyObject]()
    //添加(更新)
    dict["name"] = "zhangsan"
    dict["age"] = 18
    
    // 删除
    dict.removeValueForKey("age")
    
    // 合并字典
    var dict2 = ["name": "wangwu", "age": 80, "title": "boss"]
    for (k, v) in dict2 {
        dict.updateValue(v, forKey: k)
    }
    

    元组

    //元组(tuple)(可以放任意类型)
    //不定义标记
    let student = ("1",1,1.1,[1],[1:1])
    //访问元组元素
    print(student.4)
    //定义标记
    let student1 = (姓名:"小明",性别:"W",年龄:[19,12,20])
    //访问元组元素
    print(student1.年龄[1])
    print(student1.2[1])
    
    • 总结 :
      • 数组[index,value]:里面放着两种属性,一种是索引,一种是元素,数组中放着的只有元素,我们可以通过索引找到元素
      • 字典[key,value]:和oc中一样都放着键值对,可以通过key访问value
      • 元祖[标记,value]:可以看做是数组和字典的结合体,里面的标记可以不定义(默认像数组中的index),可以定义(就像字典中的key,但是字典中的key是有类型的,标记是无类型的)

    循环,遍历,switch,枚举

    循环和遍历

    //whlie
    while false
    {
    
    }
    //类似于do...while
    repeat
    {
    
    }while false
    // 循环
    for var i = 0; i < 10; i++ {
        print(i)
    }
    // 遍历 0 ~ 9(省略号之间不能有空格)
    for i in 0..<10 {
        print(i)
    }
    
    // 遍历 0 ~ 10(省略号之间不能有空格)
    for i in 0...10 {
        print(i)
    }
    
    // 特殊写法(如果不关心循环本身的索引,可以用通配符'_'忽略)
    for _ in 0...10 {
        print("hello")
    }
    
    
    //数组的遍历
    var studentArr = [1,2,3,4,5,6,7,8,9]
    for item in studentArr
    {
        print("item = \(item)")
    }
    //可以遍历数组中的所以和元素(间接用到了元组的特性)
    for(index,value)in studentArr.enumerate()
    {
        print("index =\(index)   value = \(value)")
    }
    //字典的遍历(同样间接用到了元组的特性)
    var studentDic = ["姓名":"张三","爱好":"男"�"]
    for (key,value)in studentDic
    {
        print("key = \(key)  value = \(value)")
    }
    

    switch和枚举

    //swtich(自带break,可以重复,但是找到一个就不会找第二个)
    var name1 = "小明"
    switch name1
    {
        case "小明":print(name1)
        //要想要自带贯穿效果(重复之后也继续寻找)加fallthrough关键字
        fallthrough
        case "小明":print(name1)
        //一定要包含所有条件
        default: print("不存在")
    }
    //case可以写区间
    var age1 = 12
    switch age1 {
    case 10...15:
        print("a")
    default:
        print("默认")
    }
    //当age2 == 15成立的时候把age2赋给age
    var age2 = 15
    switch age2{
    case let age where age2 == 15:
        print("age = \(age)")
    default: break
    }
    //遍历元祖
    var studentTuple = (姓名:"张三",性别:"男",年龄:12)
    switch studentTuple
    {
    case ("张三","男",12):
        print("找对了")
    case (_,_,12):
        print("找对了")//只要一个条件成立就可以进
    default:
        break
    }
    
    //枚举(和oc一样默认初始值是0,如果修改初始值的话需要制指定类型,swift的枚举创建必须要带case)
    enum season :Int
    {
        case spring = 2
        case summer
        case autumn
        case winter
    }
    print(season.autumn)
    //打印枚举值的值
    print(season.autumn.rawValue)
    
    var today = season.summer
    //筛选枚举
    switch today
    {
        case.spring:print("春天")
        case.summer:print("夏天")
        case.autumn:print("秋天")
        case.winter:print("冬天")
    }
    //枚举也可以这样定义(case后面跟着多个元素,枚举值的类型也可以是String类型)
    enum City:String
    {
        case 北京 = "北京",上海
        case 石家庄,武汉
        case 青岛
    }
    

    函数

    //函数
    //无参无返回
    func func1()
    {
        print("无参无返回值")
    }
    //无参有返回
    func func2()->String
    {
        print("无参有返回值")
        return "小明"
    }
    //有参无返回
    func func3 (a :String)
    {
        print("有参无返回值")
    }
    //有参有返回
    func func4 (a:Int)->String
    {
        print("有参有返回值")
        return String(a)
    }
    //函数调用
    func1()
    func2()
    func3("123")
    func4(1)
    
    //不定参数(这点与oc中的不大一样,如果传入的参数不固定可以这样写)
    func add(a:Int...)->Int
    {
        var result = 0
        for item in a
        {
            result += item
        }
        return result
    }
    //调用的时候传入的参数就是不固定的
    print(add(1,2,3,4))
    //返回值是多个参数
    func func5()->(Int,String)
    {
        return(1,String(123))
    }
    //交换
    var m = 1
    var n = 2
    //变成指针(inout)(只有改变指针才能达到换值的目的)
    //xy是外部参数,ab是内部参数,系统默认第一个不会帮我们省略,以后的参数会帮我们省略,所以要将x写出来,但是y可以省略
    func change(inout x a:Int,inout y b:Int)
    {
        let temp = a
        a = b
        b = temp
    }
    change(x: &m, y: &n)
    

    结构体和类

    • Swift要求类和结构体中的存储属性(非lazy)在对象初始化完毕后必须有值

    结构体

    • Swift里面的结构体和oc中的不太一样,苹果官方更推荐在开发中使用结构体,Swift中的结构体更像类,可以定义属性和方法
    • Swift中的结构体是值类型,也就是说在赋值的时候是拷贝一块内存空间,类似于oc中的深拷贝
    • Swift中的结构体不可以继承
    struct Father
    {
        init ()
        {
            print("______")
        }
    }
    
    //结构体
    struct Person{
        //存储属性(和@property一样)
        var name:String!
        var age:NSInteger!
        //计算属性(不会存值,依赖于其他存储属性,没有存储空间)
        var fatherAge:NSInteger
            {
                set {
                    age = newValue - 20
                }
                get {
                   return age + 20
                }
            }
        //初始化方法
        init()
        {
            print("初始化方法")
        }
        //自定义初始化方法
        init(name:String,age:NSInteger)
        {
            self.name = name
            self.age = age
        }
        //懒加载属性(用到时在加载)
       lazy var father:Father = Father()
        //类属性
        static var Arr = Array<Int>()
        //对象方法
        func eat(){
            print("吃饭")
        }
        //类方法
        static func happy() {
            print("类方法happy")
        }
    }
    

    • 类可以继承
    • 类是引用类型,赋值的过程是复制的指针,两个对象同时指向同一块内存空间,修改一个影响另一个,类似于浅拷贝
    class Person1:NSObject
    {
    //重写父类的方法必须用关键字override
        override init()
        {
            print("初始化人")
        }
    }
    class dog: NSObject
    {
        //存储属性
        var name:NSString!
        var age:NSInteger!
        //计算属性
        var fatherAge:NSInteger{
            set{
                age = newValue / 10
            }
            get {
                 return age * 10
            }
        }
        //懒加载属性
        lazy var person:Person1 = Person1()
        //类属性
        static var arr = Array<Int>()
        //类方法 (class和static都可以创建类方法,唯一的区别是用static修饰的类,其子类不可以重写该类的方法)
        static func eat()
        {
            print("吃")
        }
        //对象方法
        func happy()
        {
            print("happy")
        }
        //自定义初始化方法
        init(name:String,age :NSInteger)
        {
            self.name  = name
            self.age = age
        }
    
    }
    
    

    protocol和extension

    • 在swift中协议和oc的区别不是很大,而extension更像是oc中的category,extension不但可以给类扩展,也可以给协议扩展

    protocol

    • swift中的协议把可选协议个必须实现的协议分开
    //必须实现的协议
    protocol PersonDelegate
    {
        //对象方法
        func numberOfDog()->String
        // 类方法
        static func numberOfDog()
        //属性
        var gender:String{get set}
        //类属性
        static var classRoom:String{ get set}
    }
    
    //可选协议
    @objc protocol DogDelegate{
        optional var name:String{set get }
        //方法
        optional func eat()->String
    }
    

    extension

    • 正因为swift中的extension有这个特性,所以开发过程中我们可以充分利用extension的特性可以把我们的项目模块化(例如创建tableView的时候,两个代理可以用extension写出来)
    //扩展
    extension Person {
        func text (){
            print("asda")
        }
    }
    //创建一个类
    class Student:NSObject
    {
        var delegate:DogDelegate?
    
        override init() {
            super.init()
            self.delegate = self
        }
    //    func eat() -> String {
    //        return "123"
    //    }
    }
    
    extension Student : DogDelegate
    {
        func eat() -> String {
            return "123"
        }
    }
    

    闭包

    • swift中的闭包类似于oc中的block
    • 闭包表达式的类型和函数的类型一样(也就是in之前的部分)
    • in关键字的目的是便于区分返回值和执行语句
    • 关于闭包表达式的优化
      • 1.类型优化, 由于函数中已经声明了闭包参数的类型, 所以传入的实参可以不用写类型
      • 2.返回值优化, 同理由于函数中已经声明了闭包的返回值类型,所以传入的实参可以不用写类型
      • 3.参数优化, swift可以使用$索引的方式来访问闭包的参数, 默认从0开始
    //闭包
    var block :(Int->Void)?
    
    //实现
    block = {(a:Int) in
        return a
    }
    block!(0)
    
    //第二种写法(可以省略,$0第一个参数,$1代表第二个参数)
    var bb:(Int,String)->String
    bb = {
        return $1
    }
    bb(1,"2")
    //闭包作为函数回调
    func eat(block:(a:Int)->(Int))->Int
    {
        return block(a: 1)
    }
    
    eat { (a) -> (Int) in
        return a
    }
    

    相关文章

      网友评论

        本文标题:Swift

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