美文网首页
swift 中的关键字

swift 中的关键字

作者: paopaowuxie | 来源:发表于2019-04-11 11:39 被阅读0次

    学习swift有一段时间了,有很多关键字例如var let func class 等等很多非常常用的,在这里就不做说明了,这篇文章选取了一些区别于OC 的关键词来说一说 。

    • lazy :懒加载。swift 中我们在使用 lazy 修饰属性时,必须声明属性是变量。而且我们需要显示的指定属性的类型。对该属性进行一个赋值语句用来首次访问时使用。与OC 不同的是可以不需要判断里面是否为空,Swift懒加载的执行顺序是如果这个变量没有值,才会执行闭包。
    注意的是需要用var来修饰,因为常量必须在实例构建时赋值
    lazy var name: String = "Hello"
    lazy var nameLabel: UILabel = {
        let label = UILabel()
        label.text = "hello,swift"
        return label
     }()
    
    • struct:使用struct关键字去声明结构体,Swift中的结构体并不复杂,与C语言的结构体相比,除了成员变量,还多了成员方法。使得它更加接近于一个类。个人认为可以理解为是类的一个轻量化实现。比如:
    struct Person {
        var name:String
        var age:Int
       
        func introduce(){
            print("我叫:\(name),今年\(age)岁")
        }
    }
    
    var person = Person(name: "gp",age: 18)
    person.name = "gp"
    print("person.name = \(person.name)")
    person.introduce()
            
     /**
     输出结果为:
     person.name =gp
     "我叫:gp,今年18岁"
     */
    

    语法与C语言或者OC类似,Swift中的结构体,在定义成员变量时一定要注明类型。另外要注意一下的是,结构体属于值类型,而Swift中的类属于引用类型。
    下面扩展一下什么叫做值类型,什么是引用类型。

    值类型和引用类型实际上就是指对象的传递方式分别是 按值传递 和 按地址传递。
    值类型的赋值为深拷贝(Deep Copy),值语义(Value Semantics)即新对象和源对象是独立的,当改变新对象的属性,源对象不会受到影响,反之同理。

    除了 Int类型,诸如:CGFloat,Bool,Character,Array,struct等,这些值类型的对象都可以使用inout修饰,达到使用引用的方式传递的目的。

    引用类型的赋值是浅拷贝(Shallow Copy),引用语义(Reference Semantics)即新对象和源对象的变量名不同,但其引用(指向的内存空间)是一样的,因此当使用新对象操作其内部数据时,源对象的内部数据也会受到影响。

    举个🌰

    
    struct SomeStruct {
        var data: Int = -1
    }
    
    class SomeClass {
        var today = "Monday"
    }
    **值类型 按值传递:**
    var a = SomeStruct()
    var b = a                       // a复制一份,并将副本赋值给了b
    a.data = 42                     // a的数据改变了,但是b的并没有改变
    print("\(a.data), \(b.data)")//42,-1
    **引用类型 按址传递:**
    //引用类型的赋值行为其实是隐式的创建了一个共享的实例,作为原始类型的引用。
    //下面的例子中,两个变量都会引用唯一的那个共享实例的数据,所当改变这两个变量中任何一个的数据,都会同样作用于原始类型的数据:
    var week = SomeClass()
    var week2 = week
    week2.today = "Tues."
    print("\(week.today),\(week2.today)")//"Tues.,Tues."
    
    • inout:将值类型的对象用引用的方式传递。
      inout关键字,可以使得值类型的对象和引用类型的对象一样,以按址传递的方式进行操作,这里的操作不仅包含上述例子中的赋值操作,也包含了函数的参数传递行为。
      通俗的举个例子:我们在使用函数传递一个Int类型对象的时候,通常会将这个对象的值传递进去了。但是如果使用inout修饰对象的类型,则可以将变量的地址传入函数。就像下面这个handle函数一样。
    func test(){
        var a:Int = 5
        handle(a:&a)   //  注意这里使用了取址操作
        print(a)    // 6  
    }
    
    func handle(a:  inout Int){
        print(a)   //5
        a = a + 1     //如果没有inout修饰的话,这句代码将会报错,主要意思是不能改变一个let修饰的常量。
    }
    

    最终,我们在test 函数中打印的变量a的值被改变了。

    • override:重写。如果我们要重写某个方法, 或者某个属性的话, 我们需要在重写的变量前增加一个override关键字。
    • final: 防止重写,
    1. final不能修饰结构体和枚举
    2. final修饰符只能修饰类,表明该类不能被其他类继承,也就是它没资格当父类。
    3. final修饰符也可以修饰类中的属性、方法,但前提是该类并没有被final修饰过。
      可以将类或者类中的部分实现保护起来,从而避免子类破坏
    import UIKit
    
    class MondayClass: NSObject {
    
        final var today = "1"
        
        final func whatTheDay() {
        }
    }
    
    //如果放在class前面修饰的话 那么这个类将不能被继承
    class TestMonday: MondayClass {
        override func whatTheDay() {//Instance method overrides a 'final' instance method
            
        }
    }
    
    • typealias:
      在Swift中,使用关键字typealias定义类型别名(typealias就相当于objective-c中的typedef),就是将类型重命名,看起来更加语义化。比如:
    typealias Success = (_ result: String) -> Void
    typealias Failure = (_ error: String) -> Void
    
    func excuteNetworking(_ successBlock: Success, failBlock: Failure) {
    }
    
    
    • deinit :属于析构函数,析构函数(destructor) 与构造函数相反。当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。
      与OC 中的dealloc一个意思
      写法:
     deinit{
            self.removeObserver(self, forKeyPath: "bounds")
            NSNotificationCenter.defaultCenter().removeObserver(self)
        }
    

    一般可以用来:
    销毁对象、
    KVO移除、
    移除通知、
    NSTimer销毁等。

    • static:
      static 可以修饰存储属性,static 修饰的存储属性称为静态变量(常量)。
      static 修饰的静态方法不能被重写,class 修饰的类方法可以被重写。

    首先先来了解两个概念

    1. 存储属性:就是存储在特定类或结构体的实例中的常量或变量。例如最简单的:
    class Man {
        //可变存储属性
         var walk: Int = 20
        //不能变存储属性
        let run:Int = 100
    }
    
    1. 计算属性:不直接存储值,而是提供一个“getter”来获取值和一个可选的“setter”来设置值,例如:
        //计算属性 只有getter方法 表示只读
        var walker :Int {
            return 1
        }
        //等价于
        var walker:Int{
            get{
                return 1
            }
        }
    

    再来看一个可读可写的计算属性:

    struct Point {
        var x = 0.0, y = 0.0
    }
    struct Size {
        var width = 0.0, height = 0.0
    }
    
    struct Rect {
        var origin = Point()
        var size = Size()
        
        var center: Point {
            get {
                let centerX = origin.x + (size.width / 2)
                let centerY = origin.y + (size.height / 2)
                return Point(x: centerX, y: centerY)
            }
            set(newCenter) {
                origin.x = newCenter.x - (size.width / 2)
                origin.y = newCenter.y - (size.height / 2)
            }
        }
    }
    //赋值调用
    var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size(width: 10.0, height: 10.0))      
    print("square.origin was at (\(square.center))")//5,5 
    square.center = Point(x: 15.0, y: 15.0)
    print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
    // 输出 "square.origin is now at (10.0, 10.0)”
    

    好了,可以继续static

    class Man {
        //存储属性
        static var walk: Int = 20
        
        //计算属性
        static var run: Int{
            return 10
        }
        
        //类方法
        static func walkRace() -> Int {
            return Man.walk
        }
    }
    
    
    class SuperMan: Man {
       // Cannot override static method
       override static func walkRace() -> Int {//报错
            return 100
        }
        //Cannot override with a stored property 'walk'
       override static var walk: Int = 30//报错
        
    }
    

    但是如果是class修饰的方法和属性是可以重写的,如下:

    class Man {
        
        //存储属性
      static var walk: Int = 20//注意: 这样的存储类型是不能倍class修饰的    
        //计算属性
        class var run: Int{
            return 10
        }
        
        //类方法
        class func walkRace() -> Int {
            return Man.walk
        }
    }
    
    class SuperMan: Man {
        
        override class func walkRace() -> Int {
            return 20
        }
    

    未完待续。。。>_<

    相关文章

      网友评论

          本文标题:swift 中的关键字

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