美文网首页
13 类的构造函数、析构函数和自动引用计数

13 类的构造函数、析构函数和自动引用计数

作者: LeeLeCoder | 来源:发表于2018-05-23 10:03 被阅读0次

1. 构造函数

1.1 构造函数的介绍

  • 构造函数类似于OC中的初始化方法:init方法
  • 默认情况下创建一个类时,必然会调用一个构造函数
  • 即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数。
  • 如果是继承自NSObject,可以对父类的构造函数进行重写

1.2 构造函数的基本使用

1.2.1 构造函数的基本使用

  • 类的属性必须有值
  • 如果不是在定义时初始化值,可以在构造函数中赋值
class Person: NSObject {
    var name : String
    var age : Int

    // 重写了NSObject(父类)的构造方法
    override init() {
        name = ""
        age = 0
    }
}

// 创建一个Person对象
let p = Person()

1.2.2 初始化时给属性赋值

  • 很多时候,我们在创建一个对象时就会给属性赋值
  • 可以自定义构造函数
  • 注意:如果自定义了构造函数,会覆盖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)

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

  • 真实创建对象时,更多的是将字典转成模型
  • 注意:
    • 去字典中取出的是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)

1.2.4 字典转模型(利用KVC转化)

  • 利用KVC字典转模型会更加方便
  • 注意:
    • KVC并不能保证会给所有的属性赋值
    • 因此属性需要有默认值
      • 基本数据类型默认值设置为0
      • 对象或者结构体类型定义为可选类型即可(可选类型没有赋值前为nil)
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)

2. 析构函数

  • Swift 会自动释放不再需要的实例以释放资源
    • Swift 通过自动引用计数(ARC)处理实例的内存管理
    • 当引用计数为0时,系统会自动调用析构函数(不可以手动调用)
    • 通常在析构函数中释放一些资源(如移除通知等操作)
  • 析构函数的写法
deinit {
    // 执行析构过程
}

示例:

class Person {
    var name : String
    var age : Int

    init(name : String, age : Int) {
        self.name = name
        self.age = age
    }

    deinit {
        print("Person-deinit")
    }
}

var p : Person? = Person(name: "why", age: 18)
p = nil

3. 自动引用计数

3.1 工作机制

  • Swift和OC一样,采用自动引用计数来管理内容
  • 当有一个强引用指向某一个对象时,该对象的引用计数会自动+1
  • 当该强引用消失时,引用计数会自动-1
  • 当引用计数为0时,该对象会被销毁

3.2循环引用

  • 在通常情况下,ARC是会自动帮助我们管理内存的
  • 但是在开发中我们经常会出现循环引用的问题,比如下面的示例
    • Student对Book对象有一个强引用
    • 而Book对Student有一个强引用
    • 在两个对象都指向nil时,依然不会被销毁,就形成了循环引用
// 1.创建类
class Student {
    var book : Book?

    deinit {
        print("Student -- deinit")
    }
}

class Book {
    var owner : Student?

    deinit {
        print("Book -- deinit")
    }
}

// 2.创建对象
var stu : Student? = Student()
var book : Book? = Book()

// 3.相互引用
stu?.book = book
book?.owner = stu

// 4.对象置nil
stu = nil
book = nil
  • 解决方案
    • swift提供了两种解决方案
      • weak : 和OC中的__weak一样是一个弱引用.当指向的对象销毁时,会自动将指针指向nil
      • unowned : 和OC中的__unsafe_unretained.当对象销毁时依然指向原来的位置(容易引起野指针)
// 1.创建类
class Student {
    weak var book : Book?
    // unowned var book : Book = Book()

    deinit {
        print("Student -- deinit")
    }
}

class Book {
    var owner : Student?

    deinit {
        print("Book -- deinit")
    }
}

// 2.创建对象
var stu : Student? = Student()
var book : Book? = Book()

// 3.相互引用
stu?.book = book!
book?.owner = stu

// 4.对象置nil
stu = nil
book = nil

相关文章

  • 无标题文章

    类string的构造函数、拷贝构造函数和析构函数 引用http://www.cppblog.com/life02/...

  • 简介python中的析构函数与构造函数

    python的构造和析构函数为固定的名字。 构造函数 析构函数 不像c++中那样构造函数和析构函数是类名字。并且在...

  • 构造函数

    构造函数 构造函数的数组的应用 类中包含类,并且给类传参 析构函数(逆构造函数):每个构造函数都析构函数,谁最先构...

  • 13 类的构造函数、析构函数和自动引用计数

    1. 构造函数 1.1 构造函数的介绍 构造函数类似于OC中的初始化方法:init方法 默认情况下创建一个类时,必...

  • 日常随笔第九弹-类/构造函数/析构函数

    类及构造函数/析构函数

  • c++ 继承与派生

    派生类的构造函数和析构函数 用户在声明类时可以不定义构造函数,系统会自动设置一个默认的构造函数,在定义类对象时会自...

  • 高质量C++编程指南 ----类的构造函数、析构函数与赋值函数

    构造函数、析构函数与赋值函数是每个类最基本的函数。每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含...

  • 一个例子记住C++对象的生存周期

    代码 代码说明: 类A,含构造函数和析构函数 普通函数fun,函数体里新建了类A的局部自动对象FunObj和局部静...

  • C/C++基础(6)

    类 类的基本定义 拷贝构造函数 构造函数和析构函数 析构函数最常用于内存对象的回收,回收专门在对象内部分配的额外空...

  • C++三五法则

    1、需要析构函数的类也需要拷贝构造函数和拷贝赋值函数。 通常,若一个类需要析构函数,则代表其合成的析构函数不足以释...

网友评论

      本文标题:13 类的构造函数、析构函数和自动引用计数

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