您的位置:首页 > 产品设计 > UI/UE

ABMultiValueCopyLabelAtIndex使用不当引起的内存泄漏

2016-01-06 15:17 495 查看
http://blog.sina.com.cn/s/blog_7309637a01016q6c.html

首先给一段错误的代码:

NSString *mm = (NSString*)ABMultiValueCopyValueAtIndex(phone, i);

mm = [mm substringToIndex:1];//这时的mm已经不是原先的mm了,之前的mm被内存泄漏了

if(mm)

CFRelease((CFTypeRef)mm);

//注:phone是由一下方式获取;ABMultiValueRef phone
= ABRecordCopyValue(person,kABPersonPhoneProperty);

上面这段代码使用xcode->product->Analyze编译会得到两个警告提示:、

(1)Incorrect decrement of the reference count of an object that is not owned at this point by the caller;

(2)Potential leak of an object allocated on line 414 and stored into 'mm'

接下来再给一段正确的代码:

CFStringRef mmcf = ABMultiValueCopyValueAtIndex(phone, i);

NSString *mm = (NSString*)mmcf;

mm = [mm substringToIndex:1];//mm由NSString的系统机制自行维护

CFRelease(mmcf);

最后,为什么会这样,Why?

我们分析一下那段错误的代码:

首先,将ABMultiValueCopyValueAtIndex(phone, i)得到的结果记作变量CF,

其类型是CFString。

CFString必须使用CFRelease()来释放,否则会内存泄漏;

(NSString*)CF是类型强制转换;把CF的内容以NSString*的形式提供出来。所以(NSString*)后,本质还是CF.

于是下面这句代码

NSString *mm = (NSString*)ABMultiValueCopyValueAtIndex(phone, i);

的真正含义是:

NSString *mm = (NSString*)CF;

此时,mm和CF本质上是同一个东东;

继续看接下来的代码:

mm = [mm substringToIndex:1];

将[mm substringToIndex:1]的结果记作变量B,于是上面的的语句也可以写作:

mm=B

这时产生问题了,CF哪里去了?按照这样写代码的方式,没有办法释放CF,所以CF即将被内存泄漏了。

于是在最后一句:
if(mm)
CFRelease((CFTypeRef)mm);

释放的的内容实际是B,不是原先的CF,CF被内存泄漏了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: