四.值类型和引用类型

  1. 前面已经提到过,Swift中的类是引用类型,而枚举、结构体是只类型。  

  2. 对于前面的例子var p =  Person()来说,程序会先在堆内存里初始化一个Person实例,然后在栈内存里声明一个Person类型的变量,这个Person类型的变量实际上是一个引用,它指向实际的Person实例。所以栈内存里面的引用变量并没有真正存储实例的存储属性,实例的存储属性数据实际是放在堆内存里的。----这里可以看出,引用的实质就是指针,不过比指针更加灵活,方便。

    3. 当类的对象被创建成功后,Swift不允许直接访问堆内存中的对象,只能通过该实例对象的引用取操作该对象。  

  4. 栈内存里面可以有多个引用指向堆内存里的同一个对象。  

  5. 结构体与类是不同的,在栈内存中的结构体变量本身就保存了该结构体实例,当程序把结构体实例赋值给一个变量时,系统会将该结构体实例重新复制一份,并将该副本赋值给变量。  

  6. 由于Swift把枚举、结构体当成值类型处理,无论赋值,还是传递参数,值类型的实例都需要被复制副本。因此Swift必须将枚举、结构体设计成“轻量级”的面向对象类型,所以枚举、结构体都不支持继承。

  五.引用类型的比较

  1. 在前面的运算符介绍中,提到过两个运算符: ===和 !== 。这两个运算符只能用于引用类型变量的比较。用来比较两个引用类型的变量是否指向同一个实例。  

  2. 当两个引用类型的变量指向同一个实例时,===比较的结果为true, !==比较的结果为false;如果两个引用变量指向的实例不同时,则两个比较运算符的结构也互反。  

  六. self关键字

  1. Swift提供类一个self关键字,self关键字总是指向该方法的调用者 ----类比java,其实就是java中this关键字。  

  2. 在实例方法中,self表示调用该方法的实例;在类型方法中,self表示调用该方法的类型。  

  3. 使用场景:在局部变量和存储属性重名的情况下,局部变量会隐藏存储属性。为了在方法中强行引用存储属性,也可以使用self关键字进行区分:

class Dog
  {
  var name : String = ""
  var age : Int = 2
  init(name:String, age:Int)   ----在swift中构造器用init,self表示当前类;在Java中构造器是类名,this表示当前类
  {
  self.name = name;
  self.age = age;
  }
   
  func info()
  {
  print("my name is \(name), age is : \(age)")
  }  
  }

  补充性建议,大部分来自Apple的官方文档:

  当程序需要定义一个自定义类型时,应该用类,还是结构体。一般来说,满足以下一个或多个条件时,应该考虑使用结构体:

  (1)结构体的主要目标是用于封装少量相关的简单数据值。

  (2)如果程序需要让该实例在赋值或参数传递时会自动复制副本,则应该使用结构体。

  (3)如果程序明确该类型无须继承另一个已有的类或被其他继承,则应该使用结构体。

  (4)例如如下几种情况,就可以使用结构体

  几何形状的大小,使用结构体封装两个double属性,表示width,height;封装一个范围;封装一个三维坐标系。

 (5)在面向对象编程的时候,绝大多数情况下是使用自定义类的。