关于理解内存管理
2015-08-13 15:58
477 查看
关于理解内存管理
前言:最近一段时间比较有空,看到自己的blog很久没有更新了,所以记录下今天所学,不好的地方请大家多多指出,我会尽力改善。
1、什么是引用计数(ReferenceCount)
简单而有效的管理对象生命周期的方式。不管是oc还是swift,内存管理的方式都是基于引用计数来管理的。
2、引用计数是如何工作的
首先先让我们来说明下,以前的工程使用的时候是mrc,现在xcode新建之后肯定是arc的,那我们可以通过工程配置来修改
或者是给类添加 -fno-objc-arc编译参数来修改启动手工管理引用计数的模式。
让我们来看下下面的代码:
运行的结果如下:
当我们创建一个新对象的时候,这个对象的引用计数会加1,当有一个新的指针指向这个对象的时候,会将其引用计数加1,当不指向这个指针是,其引用计数会减1,当引用计数释放时,计数会为0,那么对象会给销毁,回收内存,那么问题来了!我们在工程打印出来是为什么会是1呢?
在巧神的书上看到的解释是:其实引用计数的管理方式和linux文件系统里面的硬链接一样,当你释放的时候,系统就知道要马上回收这个内存了,没有必要在retainCount –1 ,不管减不减1,该对象肯定会被回收,然而对象被回收后,它的所有内存区域,包括retainCount值也变的没有意义了,不把1变为0可以减少一次内存操作,加快对象的回收。
3、使用管理内存的的原则
谁申请有谁释放
4、如果旧项目会引出循环引用问题,我们可以用xcode自带的Leaks来进行检查,如下图所示:这个是我测试循环引用的截图
首先:
然后选择:
下面运行后红色的线就是循环引用问题:
具体我们可以看到在那个类的方法上出现了循环引用
说了那么内存计数,那么苹果已经给出arc给开发者,这个其实有很多好处的,可以让我们更多的去关注逻辑等功能实现,而不必要去担心内存泄露问题,不过在使用arc的时候要避免盲目的依赖,另外在ios4.3要注意的是要把weak换成__unsafe_unretained,对于遇到Core Foundation对象是需要自己去手工管理他们的引用计数的。
5、CoreFoundation对象的内存管理
底层的CoreFoundation对象,大多数是以XxxCreateWithXxx这样的方式创建的,例如:
这些对象的引用计数修改要相应的使用CFRetain 和 CFRelease 方法
这两个的使用和retain和release一样。
在使用的过程中,需要将一个CoreFoundation对象转换为一个OC对象,
* __bridge: 只做类型转换,不修改相关对象的引用计数,原来的CoreFoundation对象在不用时,需要调用CFRelease。
* __bridge_retained:类型转换后,将该对象引用计数加1,原来的CoreFoundation对象在不用时,需要调用CFRelease。
* __bridge_transfer:类型转换后,将该对象的引用计数交给arc管理,CoreFoundation对象在不用时,不需要调用CFRelease。
以上是学习到的知识点整理,如有不对,请广大朋友指点。
前言:最近一段时间比较有空,看到自己的blog很久没有更新了,所以记录下今天所学,不好的地方请大家多多指出,我会尽力改善。
1、什么是引用计数(ReferenceCount)
简单而有效的管理对象生命周期的方式。不管是oc还是swift,内存管理的方式都是基于引用计数来管理的。
2、引用计数是如何工作的
首先先让我们来说明下,以前的工程使用的时候是mrc,现在xcode新建之后肯定是arc的,那我们可以通过工程配置来修改
或者是给类添加 -fno-objc-arc编译参数来修改启动手工管理引用计数的模式。
让我们来看下下面的代码:
NSLog(@"reference count = %u",[object retainCount]); NSObject *another = [object retain]; NSLog(@"reference count = %u",[object retainCount]); [another release]; NSLog(@"reference count = %u",[object retainCount]); [object release];
运行的结果如下:
当我们创建一个新对象的时候,这个对象的引用计数会加1,当有一个新的指针指向这个对象的时候,会将其引用计数加1,当不指向这个指针是,其引用计数会减1,当引用计数释放时,计数会为0,那么对象会给销毁,回收内存,那么问题来了!我们在工程打印出来是为什么会是1呢?
在巧神的书上看到的解释是:其实引用计数的管理方式和linux文件系统里面的硬链接一样,当你释放的时候,系统就知道要马上回收这个内存了,没有必要在retainCount –1 ,不管减不减1,该对象肯定会被回收,然而对象被回收后,它的所有内存区域,包括retainCount值也变的没有意义了,不把1变为0可以减少一次内存操作,加快对象的回收。
3、使用管理内存的的原则
谁申请有谁释放
4、如果旧项目会引出循环引用问题,我们可以用xcode自带的Leaks来进行检查,如下图所示:这个是我测试循环引用的截图
首先:
然后选择:
下面运行后红色的线就是循环引用问题:
具体我们可以看到在那个类的方法上出现了循环引用
说了那么内存计数,那么苹果已经给出arc给开发者,这个其实有很多好处的,可以让我们更多的去关注逻辑等功能实现,而不必要去担心内存泄露问题,不过在使用arc的时候要避免盲目的依赖,另外在ios4.3要注意的是要把weak换成__unsafe_unretained,对于遇到Core Foundation对象是需要自己去手工管理他们的引用计数的。
5、CoreFoundation对象的内存管理
底层的CoreFoundation对象,大多数是以XxxCreateWithXxx这样的方式创建的,例如:
CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, "hahah", kCFStringEncodingUTF8); CTFontRef fontRef = CTFontCreateWithName((CFStringRef)@"ArialMT", 14.0f, NULL);
这些对象的引用计数修改要相应的使用CFRetain 和 CFRelease 方法
CFRetain(str); CFRelease(str);
这两个的使用和retain和release一样。
在使用的过程中,需要将一个CoreFoundation对象转换为一个OC对象,
* __bridge: 只做类型转换,不修改相关对象的引用计数,原来的CoreFoundation对象在不用时,需要调用CFRelease。
* __bridge_retained:类型转换后,将该对象引用计数加1,原来的CoreFoundation对象在不用时,需要调用CFRelease。
* __bridge_transfer:类型转换后,将该对象的引用计数交给arc管理,CoreFoundation对象在不用时,不需要调用CFRelease。
以上是学习到的知识点整理,如有不对,请广大朋友指点。
相关文章推荐
- nginx 中 PHP 调用PEAR.php遇到的问题
- TXT 与 DataTable 互转
- 获取windows可执行文件的version信息(版本号)
- easy.py使用中ValueError: could not convert string to float: svm_options错误问题解决
- 当前选中 底色切换
- 解决centos netstat和ps感染木马
- function, method, unbound_method, bound_method
- meta标签中的http-equiv属性使用介绍
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
- Linux上 安装JDK环境变量配置 新手必备
- js实现仿网易点击弹出提示同时背景变暗效果
- Dubbo源码分析——扩展点机制
- 用ant实现java项目的自动构建和部署
- 控制翻转(IOC)与 依赖注入 (DI)
- LoadRunner脚本 《第二篇》
- 【NOI2015】【软件包管理器】【树链剖分】
- hdu 1754__I Hate It
- 数组不初始化的默认值
- android SQLite使用SQLiteOpenHelper类对数据库进行操作
- 在Android中applicationId与package name的那些事