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 ...
随机推荐
- 4、项目的培训 - PMO项目管理办公室
培训是一个重要的内容,在公司内部就有相关的培训.对于PMO项目管理办公室来说,就是相关的项目的技术和业务的培训,以期让项目组人员能够快速的学习好项目业务内容和所需要使用到的技术内容,然后尽快的进入项目 ...
- 如何定义好一个符合规范的url
描述 进公司没有多久遇到一个问题,定义的url会被大神吐槽说是很渣.之前从来没有注意这块,今天把我们团队的url规范分享给大家. 为什么需要URL规范化 1.网站URL和结构已经成为网站搜索引擎友好的 ...
- sql server中substring的用法
SQL 中的 substring 函数是用来截取一个栏位资料中的其中一部分. 例如,我们需要将字符串'abdcsef'中的'abd'给提取出来,则可用substring 来实现: ,) 结果: 'ab ...
- PHP curl 函数
转载http://sunking.sinaapp.com/archives/111 最近使用curl的时候,发现了一个比较好用的函数,当然是初级者适用的一个函数,就是curl_getinfo(), 在 ...
- 【转】(超详细)jsp与servlet之间页面跳转及参数传递实例
初步学习JavaEE,对其中jsp与Servlet之间的传值没弄清楚,查看网上资料,发现一篇超详细的文章,收获大大,特此记录下来.具体链接:http://blog.csdn.net/ssy_shand ...
- 《Note --- Unreal 4 --- behavior tree》
Web: https://docs.unrealengine.com/latest/INT/Engine/AI/BehaviorTrees/index.html Test project: D:\En ...
- Ural 1225. Flags 斐波那契DP
1225. Flags Time limit: 1.0 secondMemory limit: 64 MB On the Day of the Flag of Russia a shop-owner ...
- TCP协议学习
一.TCP参考模型 VS OSI参考模型 二.TCP/IP分层模型的四个协议层分别完成以下的功能 第一层 网络接口层 网络接口层包括用于协作IP数据在已有网络介质上传输的协议.实际上TCP/IP标准 ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- Android开发之扫描二维码开发
原贴地址:http://www.cnblogs.com/Fndroid/p/5540688.html 二维码其实有很多种,但是我们常见的微信使用的是一种叫做QRCode的二维码,像下面这样的,可以放心 ...