Swift中的可选链与内存管理(干货系列)
干货之前:补充一下可选链(optional chain)
class A {
var p: B?
}
class B
{
var p: C?
}
class C {
func cm() -> String {
print("cm")
return "abc"
}
}
let insa = A()
let insb = B()
let insc = C()
insa.p = insb
//insa.p = nil
insb.p = insc
let r = insa.p?.p?.cm()
解析:此处定义了A,B,C三个类,使其依次关联,最后通过类A实例的属性拿到B实例,依次拿到C实例再调用C的方法。
注意:1,中间任何一个地方为nil,不报错,但导致整个结果为nil。
2,如果没有一个地方为nil,整个表达式才正常执行。
内存管理
swift中的或者java,c#语言的内存管理,指的就是引用类型对象的管理,也就是对“堆(heap)”里面的对象的管理。
这三种语言中,值类型不需要进行内存管理,值类型是放在栈里的,程序会自动管理,不需要特别的机制。
swift中的内存管理技术,叫做arc,自动引用计数(Auto Reference Count) 当对对象的引用计数为0时,立即销毁对象
这种管理一般会产生两种错误可能
1.空引用
2.内存泄露(leak) 某个时候,某些对象分配了内存,但因为某些原因,导致程序结束时,此对象所占的内存没有被回收
我们可以控制的引用计数的数量 增加的方法 1.声明变量,指向某个对象(直接new或者把别的变量的值赋值给你 )
减少的方法
1.f = nil(表示不指向任何东西)
2.变量一般会运行在函数中,变量本身是存放在栈中的 所以函数结束时,此变量消失
关于循环引用swift提供了两种方法来解决,
一种是weak(弱),一种是unowned(未拥有)
1.weak 可以修饰在可为空(?,!)的属性上
2.unowned只能修饰在非可为空的属性上。
循环引用案例
class A {
var p: B?
init() {
print("a********************")
}
deinit {
print("a--------------------")
}
}
class B{
var p: A?
init() {
print("b********************")
}
deinit {
print("b--------------------")
}
}
var f1:A? = A()
var f2:B? = B()
//使用这两个类时,可以从控制台看到这两个类已经初始化完毕
//通过f1f2两个对象的属性将这两个类相互关联
f1?.p = f2
f2?.p = f1
//此时再将这两个对象赋值为nil
//f1 = nil
//f2 = nil
//但此时并没有调用类的析构函数
//原因:f1f2这两个对象的属性相互引用了这两个对象
f1?.p = nil
f2?.p = nil
f1 = nil
f2 = nil

解析:1,此处现将f1f2两对象的属性赋值为nil再将f1f2赋值为nil即代表A,B这两个类完全没有引用,此时才会调用析构函数,回收内存。
2,以上这种循环引用的问题,对象并没有真正清除常常会导致内存泄漏(leak)
解决方法一:weak
class C {
var p: D?
init() {
print("c********************")
}
deinit {
print("c--------------------")
}
}
class D{
weak var p: C?
init() {
print("d********************")
}
deinit {
print("d--------------------")
}
}
var f3:C? = C()
var f4:D? = D()
f3 = nil
f4 = nil
此时发现在任何一个循环引用的属性上加上weak关键字,即可解决上述问题
注意:weak 可以修饰在可为空(?,!)的属性上
解决方式二:unowned
class E {
var p: F?
init() {
print("e********************")
}
deinit {
print("e--------------------")
}
}
class F{
unowned var p: E
init(a:E) {
p = a
print("f********************")
}
deinit {
print("f--------------------")
}
}
var f5:E? = E()
var f6:F? = F(a:f5!)
f5 = nil
f6 = nil
注意:unowned只能修饰在非可为空的属性上。
Swift中的可选链与内存管理(干货系列)的更多相关文章
- C++中的垃圾回收和内存管理
最开始的时候看到了许式伟的内存管理变革系列,看到性能测试结果的时候,觉得这个实现很不错,没有深入研究其实现.现在想把这个用到自己的一个项目中来,在linux下编译存在一些问题,所以打算深入研究一下. ...
- swift中的可选类型
可选类型也是Swift语言新添加的对象.主要是为了解决对象变量或常量为空的情况.在前面定义的变量和常量都不能为空.里面必须要有值. Swift中的可选类型则允许变量(常量)中没有值(被设为nil).要 ...
- swift 学习- 19 -- 可选链式调用
// 可选链式调用 是一种在当前值可能为 nil 的可选值上请求 和 调用属性, 方法以及下标, 如果 可选值有值, 那么调用就会成功, 如果可选值是 nil, 那么就会将返回 nil , // 多个 ...
- 高端内存映射之vmalloc分配内存中不连续的页--Linux内存管理(十九)
1 内存中不连续的页的分配 根据上文的讲述, 我们知道物理上连续的映射对内核是最好的, 但并不总能成功地使用. 在分配一大块内存时, 可能竭尽全力也无法找到连续的内存块. 在用户空间中这不是问题,因为 ...
- Swift 值类型和引用类型的内存管理
1.内存分配 1.1 值类型的内存分配 在 Swift 中定长的值类型都是保存在栈上的,操作时不会涉及堆上的内存.变长的值类型(字符串.集合类型是可变长度的值类型)会分配堆内存. 这相当于一个 &qu ...
- Java中的垃圾回收机制&内存管理&内存泄漏
1. Java在创建对象时,会自动分配内存,并当该对象引用不存在的时候,释放这块内存. 为什么呢? 因为Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所 ...
- Swift中的可选协议和方法的历史渊源
@objc protocol Transaction { func commit() -> Bool optional func isComplete() -> Bool } 以上协议被标 ...
- 使用Boost库中的组件进行C++内存管理
C++标准库中的auto_ptr,智能指针,部分的解决了获取资源自动释放的问题 在Boost中,提供了6中智能指针:scoped_ptr, scoped_array, shared_ptr, shar ...
- C++中的垃圾回收和内存管理(续)
boost memory的gc_allocator的使用 首先编译生成boost-memory的库,由于生成的是.so的动态库,所以需要在运行程序之前,将库文件的路径添加到LD_LIBRARY_PAT ...
随机推荐
- React Native 之TabBarIOS
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
- [Modern OpenGL系列(一)]十步搞定OpenGL开发环境
本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51292143 OpenGL官网:https://www.opengl.or ...
- MySQL 处理重复数据
有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据. 本博文我们将为大家介绍如何防止数据表出现重复数据及如何删除数据表中的重复数据. 防 ...
- Windows下磁盘分配操作
问题概述:在装系统的时候有时候并不能一下分出完全符合我们使用习惯的分区大小,我们可能需要在后期调整分区大小.以下是有关分区大小调整的操作. 使用工具:Windows磁盘管理工具. 操作步骤: 1.使用 ...
- Tensorflow 官方版教程中文版
2015年11月9日,Google发布人工智能系统TensorFlow并宣布开源,同日,极客学院组织在线TensorFlow中文文档翻译.一个月后,30章文档全部翻译校对完成,上线并提供电子书下载,该 ...
- (一)java arcgis开发环境搭建
一,整个开发环境 OS:Win7 Development: eclipse 4.3.2 框架:spring+springMVC+mybatis+jquery Arcgis版本:10.2 desktop ...
- [LeetCode] Path Sum III 二叉树的路径和之三
You are given a binary tree in which each node contains an integer value. Find the number of paths t ...
- Dao跨事务调用实现转账功能
1.首先在数据库当中创建数据库,并且创建它的 实现类 package com.beiwo.epet.entity; public class Account { private int id; pri ...
- Android----消息弹出框
关于Android的知识,自从工作了就没有什么时间去总结学习过的知识,我个人比较喜欢学习后总结,今天就写一下关于android中消息弹出框的几种方式的简单示例,按照自己的思路写了一段,希望对和我一样在 ...
- DDNS动态更新
/// <summary> /// DnsPod DDNS工具类 /// </summary> public class DDNSToolkit { private stati ...