Swift编程中用以管理内存的自动引用计数详解_Swift

Swift 内存管理功能是通过使用自动引用计数(ARC)来处理。ARC用于初始化和取消初始化所述系统资源,从而释放使用的类实例的存储器空间当实例不再需要。ARC跟踪代码的实例有效地管理存储资源之间的关系的信息。

ARC的功能

  • 在每一次一个新的类实例被创建时ARC分配一块内存以存储信息 init()
  • 关于实例类型和其值的信息存储在存储器中
  • 当类实例不再需要它自动由 deinit() 释放,用于进一步类实例的存储和检索的存储空间
  • ARC保存在磁道当前参照类实例的属性,常量和变量,使得 deinit() 仅适用于那些不使用的实例。
  • ARC维护“强引用”这些类实例属性,常量和变量来限制释放当当前的类实例正在使用。

ARC 程序

复制代码 代码如下:

class StudDetails {
    var stname: String!
    var mark: Int!
    init(stname: String, mark: Int) {
        self.stname = stname
        self.mark = mark
    }
   
    deinit {
        println("Deinitialized \(self.stname)")
        println("Deinitialized \(self.mark)")
    }
}

let stname = "swift"
let mark = 98

println(stname)
println(mark)

当我们使用 playground 运行上面的程序,得到以下结果。

swift
98

ARC 强参考周期类实例

复制代码 代码如下:

class studmarks {
    let name: String
    var stud: student?
   
    init (name: String) {
        println("Initializing: \(name)")
        self.name = name
    }
   
    deinit {
        println("Deallocating: \(self.name)")
    }
}

class student {
    let name: String
    var strname: studmarks?
   
    init (name: String) {
        println("Initializing: \(name)")
        self.name = name
    }
   
    deinit {
        println("Deallocating: \(self.name)")
    }
}

var shiba: studmarks?
var mari: student?

shiba = studmarks(name: "Swift")
mari = student(name: "ARC")

shiba!.stud = mari
mari!.strname = shiba

当我们使用 playground 运行上面的程序,得到以下结果。

Initializing: Swift
Initializing: ARC

ARC弱和无主参考
Class类型属性有两种方法可以解决强引用周期:

  1. 弱引用
  2. 无主参考

这些引用是用来使一个实例指在一个基准周期其他实例。然后实例可以为每一个实例参考代替处理强引用周期。当用户知道某些情况下可能会返回 'nil' 值,我们可能会指向使用弱引用。当实例会返回不是零的东西,然后使用无主参考声明。

弱引用程序

复制代码 代码如下:

class module {
    let name: String
    init(name: String) { self.name = name }
    var sub: submodule?
    deinit { println("\(name) Is The Main Module") }
}

class submodule {
    let number: Int
   
    init(number: Int) { self.number = number }
   
    weak var topic: module?
   
    deinit { println("Sub Module with its topic number is \(number)") }
}

var toc: module?
var list: submodule?
toc = module(name: "ARC")
list = submodule(number: 4)
toc!.sub = list
list!.topic = toc

toc = nil
list = nil

当我们使用 playground 运行上面的程序,得到以下结果。

ARC Is The Main Module
Sub Module with its topic number is 4

无主参考程序

复制代码 代码如下:

class student {
    let name: String
    var section: marks?
   
    init(name: String) {
        self.name = name
    }
   
    deinit { println("\(name)") }
}
class marks {
    let marks: Int
    unowned let stname: student
   
    init(marks: Int, stname: student) {
        self.marks = marks
        self.stname = stname
    }
   
    deinit { println("Marks Obtained by the student is \(marks)") }
}

var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil

当我们使用 playground 运行上面的程序,得到以下结果。

ARC
Marks Obtained by the student is 98

闭包强引用周期
当我们分配一个闭包至类实例属性,闭包的主体以捕获特定实例强参考周期发生。强引用闭合由 self.someProperty 或 self.someMethod()定义。强引用周期用作闭包引用类型。

复制代码 代码如下:

class HTMLElement {
    let samplename: String
    let text: String?
   
    lazy var asHTML: () -> String = {
        if let text = self.text {
            return "<\(self.samplename)>\(text)</\(self.samplename)>"
        } else {
            return "<\(self.samplename) />"
        }
    }
   
    init(samplename: String, text: String? = nil) {
        self.samplename = samplename
        self.text = text
    }
   
    deinit {
        println("\(samplename) is being deinitialized")
    }
}

var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
println(paragraph!.asHTML())

当我们使用 playground 运行上面的程序,得到以下结果。

<p>Welcome to Closure SRC</p>
弱和无主参考
当闭包和实例相互引用,用户可以定义在一个闭合作为无主引用捕获。它不会允许用户在同一时间解除分配实例。当实例在某个时候返回一个“nil” 定义并使用弱实例的值。

复制代码 代码如下:

 class HTMLElement {
    let module: String
    let text: String?
   
    lazy var asHTML: () -> String = {
        [unowned self] in
        if let text = self.text {
            return "<\(self.module)>\(text)</\(self.module)>"
        } else {
            return "<\(self.module) />"
        }
    }
   
    init(module: String, text: String? = nil) {
        self.module = module
        self.text = text
    }
   
    deinit {
        println("\(module) the deinit()")
    }
}

var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
println(paragraph!.asHTML())
paragraph = nil

当我们使用 playground 运行上面的程序,得到以下结果。

<Inside>ARC Weak References</Inside>
Inside the deinit()

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索arc
swift
swift 引用计数、swift socket编程、swift函数式编程、苹果编程语言swift、swift在线编程,以便于您获取更多的相关知识。

时间: 2024-09-20 00:11:04

Swift编程中用以管理内存的自动引用计数详解_Swift的相关文章

Android编程中的四大基本组件与生命周期详解_Android

本文实例讲述了Android编程中的四大基本组件与生命周期.分享给大家供大家参考,具体如下: Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应. Activity之间通过Intent进行通信.在Intent 的描述结构中,有两个最

Java多线程编程中使用Condition类操作锁的方法详解_java

Condition的作用是对锁进行更精确的控制.Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法.不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的:而Condition是需要与"互斥

Shell编程中while与for的区别及用法详解_linux shell

在shell编程中经常用到循环,常用的循环有for和while循环两种.while循环默认以行读取文件,而for循环以空格读取文件切分文件,本篇就结合现网的一些使用示例说说二者的用法和区别. 一.常用语法 1.for循环 for循环常用的语法结构有如下几种: for 变量 in seq字符串 for 变量 in `command` " " for 变量 in "$@"或"$*" for((赋值:条件:运算语句)) 2.while循环 while循

js中dijit.form.DateTextBox日期自动转化方法详解

调查了一下,可以用下面的代码来解决. 如下代码:  代码如下 复制代码 dojo.declare("net.yutuo.dojo.DateTextBox", [dijit.form.DateTextBox], {        validator: function(value, constraints) {         value = this.myParse(value, constraints);         return (new RegExp("^(?:&q

Swift编程中的初始化与反初始化完全讲解_Swift

初始化类,结构和枚举当 Swift 声明后准备初始化类实例.初始值被初始化为存储属性,并且新的实例的值也被进一步进行初始化.创建初始化函数的关键字是通过 init() 方法.Swift 初始化不同于 Objective-C,它不返回任何值.其作用是检查新创建的实例的其处理前初始化.Swift 还提供了"反初始化"过程中执行的内存管理操作当实例被释放. 对于存储的属性初始化器的作用 存储的属性处理实例之前初始化类和结构的实例. 存储属性使用初始分配和初始化值,从而消除了需要调用属性观察者

实例讲解Swift中引用类型的ARC自动引用计数_Swift

一.引言 ARC(自动引用计数)是Objective-C和Swift中用于解决内存管理问题的方案.在学习Objective-C编程时经常会学习到一个关于ARC的例子:在一个公用的图书馆中,每次进入一人就将卡插入,走的时候将自己的卡拔出拿走.图书馆系统会判定只要有卡插入,就将图书馆的灯打开,当所有卡都被取走后,将图书馆的灯关掉.这个例子对应于Objective-C中的对象声明周期管理十分贴切.每当一个对象增加一个引用时,其引用计数会加1,当一个引用被取消时,对象的引用计数减1,当引用计数减为0时,

obj-c编程11:内存管理和ARC(自动引用计数)

    乖乖隆地洞,这篇文章内容可是不得了,内存管理哦!首先,这个要是搞不明白,你就等着进程莫名其妙的挂死,或是疯狂申请内存却不释放,结果被OS杀死,不管是"自杀"还是"他杀",都不是那么好玩的哦.其次要记住这可不是windows 中的内存管理(Win32 api),也不是linux中C like的内存管理方法.这个比他们都"高级"的多啊!但是没有ruby的高级,也没有ruby的简单,如果mac编程用ruby的就好了,这不搞出一个雨燕(SWFIT

窥探Swift编程中的错误处理与异常抛出_Swift

在Swift 2.0版本中,Swift语言对其错误处理进行了新的设计,当然了,重新设计后的结果使得该错误处理系统用起来更爽.今天的主题就是系统的搞一下Swift中的错误处理,以及看一下Swift中是如何抛出异常的.在编译型语言中,错误一般分为编译错误和运行时错误.我们平时在代码中处理的错误为运行时错误,我们对异常进行处理的操作的目的是为了防止程序出现错误而导致其他的副作用,比如用户数据未保存等等. 在今天的文章中,先给出主动产生异常的几种情况,然后再给出如何处理被动异常. 一.主动退出程序的几种

浅谈Swift编程中switch与fallthrough语句的使用_Swift

在 Swift 中的 switch 语句,只要第一个匹配的情况(case) 完成执行,而不是通过随后的情况(case)的底部,如它在 C 和 C++ 编程语言中的那样.以下是 C 和 C++ 的 switch 语句的通用语法: 复制代码 代码如下: switch(expression){    case constant-expression  :       statement(s);       break; /* optional */    case constant-expressio