swift 中的关键字

2019-04-11  本文已影响0人  paopaowuxie

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

注意的是需要用var来修饰,因为常量必须在实例构建时赋值
lazy var name: String = "Hello"
lazy var nameLabel: UILabel = {
    let label = UILabel()
    label.text = "hello,swift"
    return label
 }()
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."
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的值被改变了。

  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 Success = (_ result: String) -> Void
typealias Failure = (_ error: String) -> Void

func excuteNetworking(_ successBlock: Success, failBlock: Failure) {
}

 deinit{
        self.removeObserver(self, forKeyPath: "bounds")
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

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

首先先来了解两个概念

  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
    }

未完待续。。。>_<

上一篇 下一篇

猜你喜欢

热点阅读