CoreFoundation对象的内存管理
近来没什么新项目做,想学习一些swift开源项目,看了几个文件感觉有点懵,可能水平还没达到,等用到具体内容的时候再去仔细看吧。
关于现在的项目,想想单元测试还可以完善一下,就在framwork工程中写了一些测试用例。准备开始测试之前,先用product-analyze(快捷键cmd+shift+b)分析一下,发现有未释放的对象。
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
NSString *strUUID = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault,uuidRef));
NSData *deviceid = [strUUID dataUsingEncoding:NSUTF8StringEncoding];
CFRelease(uuidRef);//Potential leak of an object stored into 'uuidRef'
原来是在创建uuid的方法中,没有释放uuidRef这个cf对象,最后加上CFRelease就可以了。
但是在上面的第二行代码中,有CFBridgingRelease方法,表示把cf对象转换为oc对象,包括所有权转换,之后可以由arc自动释放对象。
再仔细看过后,发现原来上面的代码中其实有两个cf对象,把第二行中拆分成下面这样,其中__bridge可以把cf对象转为oc对象,不包括所有权转换,所以最后面有CFRelease释放stringRef对象。
再次运行analyze,又报其它错误
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef stringRef = CFUUIDCreateString(kCFAllocatorDefault,uuidRef);
NSString *uuid = (__bridge NSString *)stringRef;
NSData *deviceId = [uuid dataUsingEncoding:NSUTF8StringEncoding];
CFRelease(uuidRef);//Potential leak of an object stored into 'uuidRef'
CFRelease(stringRef);//Reference-counted object is used after it is released
对象释放之后仍然有使用,创建对象,使用完毕后释放对象,很对的,难道什么地方写得不对吗?
在stackoverflow上找到类似的问题及解决方法,比较之后发现是需要重新拷贝一份uuid对象,因为在调用CFRelease之后,之前的uuid会被释放掉,再把之前的uuid作为函数返回值返回时,就会报错。
最后正确的写法改为
//(NSString *)CFBridgingRelease(stringRef) 相当于__bridge__transfer把cf对象转成oc对象,所有权也由cf转到oc,arc下会自动释放
//__bridge 只是把cf对象转为oc,不包含所有权的转换
//CFBridgingRetain(id) 相当于__bridge__retained把oc对象转为cf对象,所有权也由oc转到cf,需要手动释放
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef stringRef = CFUUIDCreateString(kCFAllocatorDefault,uuidRef);
NSString *uuid = [NSString stringWithString:(__bridge NSString *)stringRef];
NSData *deviceId = [uuid dataUsingEncoding:NSUTF8StringEncoding];
CFRelease(uuidRef);//Potential leak of an object stored into 'uuidRef'
CFRelease(stringRef);//Reference-counted object is used after it is released
看左侧的博客目录发现三月份竟然一篇都没有写,上个月是有点荒废了,事情有点多。之后尽量保持每月至少一篇技术博客,多学习一些东西,找到值得记录的内容。加油吧!
CoreFoundation对象的内存管理的更多相关文章
- Objective-C之集合对象的内存管理
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- oc-31-多对象的内存管理
在每个OC对象内部,都专门有8个字节的存储空间来存储引用计数器. 引用计数器的常见操作 retain消息:堆内存中对象的计数器变量 +(该方法返回对象本身,要想计数器变量加1就要调用对象的retain ...
- block没那么难(三):block和对象的内存管理
本系列博文总结自<Pro Multithreading and Memory Management for iOS and OS X with ARC> 在上一篇文章中,我们讲了很多关于 ...
- Java进阶2 数组内存和对象的内存管理知识
Java进阶2 数组内存和对象的内存管理知识 20131028 前言: 在面试的时候,如果是Java的编程语言,也许你认为没有什么可以问的,只能够说明你对于Java了解的太浅了,几乎就是两个星期的节奏 ...
- oc56--ARC多个对象的内存管理
// main.m // ARC中多个对象的内存管理:ARC的内存管理就是MRC的内存管理(一个对象释放的时候,必然会把它里面的对象释放),只不过一个是Xcode加的代码,一个是我们自己加的代码: / ...
- 用"僵尸对象"调试内存管理问题
Cocoa提供了"僵尸对象"(Zombie Object)这个功能.启用这项调试功能之后,运行时系统会把所有已经回收的实例转化成特殊的"僵尸对象",而不会真正回 ...
- oc对象的内存管理
oc没有java的垃圾回收机制,所以对象的内存释放很重要,基本数据类型,我们不用理会,编译器会处理: oc的每个对象内部都由一个计数器,用来记录当前有几个指针在指向该对象:当计数器为0时该对象会从内存 ...
- oc55--ARC单个对象的内存管理
// Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @end // Person.m #i ...
- iOS 对象的内存管理细节
通过类创建对象 1.创建对象时,开辟存储空间,通过new方法创建的对象会在 堆 内存中开辟一块存储空间 2初始化所有属性都在堆内存中完成 3.返回值真地址,指针在栈内存中,指针指向的地址是堆里创建对象 ...
随机推荐
- Ubuntu16.10上安装NodeJS6.9.2
1.下载 https://nodejs.org/en/download/ 2.解压 tar -xJf node-v6.9.2-linux-x64.tar.xz 3. 移到通用的软件安装目录 /opt/ ...
- 语义SLAM的数据关联和语义定位(四)多目标测量概率模型
多目标模型 这部分想讲一下Semantic Localization Via the Matrix Permanent这篇文章的多目标测量概率模型.考虑到实际情况中,目标检测算法从单张图像中可能检测出 ...
- 绝对良心提供百度网盘的jdk1.8源码下载包含sun包的
但是openjdk网站有提供的: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/6bfaecb8ff77/src/share/classes/ 或者直 ...
- javascript获取网页各种高宽及位置总结
screen对象 获取屏幕的高宽(分辨率) screen.width //屏幕的宽 screen.height //屏幕的高 screen.availWidth //屏幕可用宽度 屏幕的像素高度减去系 ...
- LeetCode题解之Binary Number with Alternating Bits
1.题目描述 2.问题分析 将数值转换为二进制,然后将前面的 0 去掉,再遍历一边二进制字符串,对每个字符和其后部的字符进行比较. 3.代码 bool hasAlternatingBits(int n ...
- 用JS实现控制浏览器F12与右键功能
本文出至:新太潮流网络博客 用JS实现控制浏览器F12与右键功能,防止恶意窃取代码,或其他直接复制进去就好 //禁用右键 document.oncontextmenu = function () { ...
- MySQL索引原理及慢查询优化-zz
https://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所 ...
- 【待补充】[Spark Core] Spark 实现标签生成
0. 说明 在 IDEA 中编写 Spark 代码实现将 JSON 数据转换成标签,分别用 Scala & Java 两种代码实现. 1. 准备 1.1 pom.xml <depend ...
- Linux运维之--LVS、Nginx、HAproxy有什么区别?
LVS: 是基于四层的转发 HAproxy: 是基于四层和七层的转发,是专业的代理服务器 Nginx: 是WEB服务器,缓存服务器,又是反向代理服务器,可以做七层的转发 区别: LVS由于是基于四层的 ...
- mysql 错误2203 1061 及安装最后出现2003现象的解决办法
错误描述 : 1.#2003-服务器没有响应MySQL无法启动 2.Can''t connect to MySQL server on ''localhost'' (10061) 3.ERROR 20 ...