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.返回值真地址,指针在栈内存中,指针指向的地址是堆里创建对象 ...
随机推荐
- chrome中workspace配置达到同步修改本地文件的作用
在前端开发中,我们经常需要在浏览器中进行调试,特别是一些样式的修改,如果你还是先在浏览器elements中调试好在复制到本地文件,那就真的out了. chrome浏览器的workspace功能完全可以 ...
- java 使用 引用数据类型(以Scanner、Random模块为例)
创建一个新变量 类型 变量名 = new 类型() 举个例子: Scanner sc = new Scaner() 使用引用数据类型中的功能: 变量.功能名字() Scanner类:接受键盘输入 1. ...
- 文档撰写思路与排版(hadoop)
这几天在写项目提交的几个报告,写完回想了一下,在写作框架确定与排版上浪费了不少时间,特此总结一下思路. 这个写完回家过年了....emmmm 1. 定好大标题框架,使用自动添加序号,先不着急修改样式 ...
- 检索 COM 类工厂中 CLSID 为 {00021A20-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80080005
创建Excel对象失败: Excel.Application xApp = new Excel.Application(); 错误提示:{"检索 COM 类工厂中 CLSID 为 {0002 ...
- 第 15 章 位操作(invert4)
/*------------------------------------ invert4.c -- 使用位操作显示二进制 ------------------------------------* ...
- iOS 固定定位不兼容、input获取焦点后位置不对。
第一次写博客~ 大家悠着看,有则改之,无则加冕,对不对的给个回复,让我知道你的存在. 在做活动页的时候,经常会碰到一些需要弹出显示的输入框(情节前提:本人安卓机~),前天自己写的时候自己调试没问题后 ...
- November 11th, 2017 Week 45th Saturday
Happiness is a direction, not a place. 快乐是一个方向,不是一个目的. Do you remember those moments in your life wh ...
- 使用C#删除一个字符串数组中的空字符串
C#中要如何才能删除一个字符串数组中的空字符串呢?随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化.以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和过滤.C#3. ...
- skimage 安装和子模块
平台:Windows 10 1.安装anaconda anaconda是python环境的集成安装软件,建议安装2.7版本的python 2.安装skimage 打开windows的命令提示符: 输 ...
- Angular简介与程序架构
什么是angularJs 基于javascript开发的客户端应用框架,使我们可以更加快捷,简单的开发web应用. 诞生于2009年,后来被google收购,用在了很多项目中. 适用于CRUD应用或者 ...