iOS 12检测内存泄漏Analyze-Potential leak of an object stored into

IOS性能调优系列:Analyze静态分析

XCode已经提供了非常强大的性能调优工具,结合几个第三方工具和一些技巧,进行性能优化非常简单。

第一篇先写写最简单的,Analyze静态分析。

相信IOS开发者在App进行Build或Archive时,会产生很多编译警告,这些警告是编译时产生的,静态分析的过程也类似,在XCode Product菜单下,点击Analyze对App进行静态分析。


Analyze主要分析以下四种问题:

1、逻辑错误:访问空指针或未初始化的变量等;

2、内存管理错误:如内存泄漏等;

3、声明错误:从未使用过的变量;

4、Api调用错误:未包含使用的库和框架。

Analyze内存泄漏分析:

声明错误、逻辑错误、Api调用错误基本在编译时都会有警告,Analyze的主要优势在于静态分析内存泄漏及代码逻辑错误。

比如在开启arc的环境下,输入以下一段代码:

ARC 和 非ARC 下 oc 对象 和 CF 对象的转换

标签:objective-c内存泄露CoreFundation

2014-03-11 11:301231人阅读评论(0)收藏举报

分类:

IOS开发(123)

版权声明:本文为博主原创文章,未经博主允许不得转载。

在OC和FC之间进行转化的时候,主要是对象的归属问题。共有两种方式:

1、使用宏,可以标识归属者从OC到CF,还是从CF到OC。

[objc]view plaincopy

NS_INLINE CFTypeRef CFBridgingRetain(idX) {

return(__bridge_retain CFTypeRef)X;

}

NS_INLINEidCFBridgingRelease(CFTypeRef X) {

return(__bridge_transferid)X;

}

2、使用转化符,如:__bridge,__bridge_transfer,__bridge_retained

__bridge:不涉及对象所有关系改变

__bridge_transfer:给予 ARC 所有权

__bridge_retained:解除 ARC 所有权

[objc]view plaincopy

idmy_id;

CFStringRef my_cfref;

NSString   *a = (__bridge NSString*)my_cfref;// Noop cast.

CFStringRef b = (__bridge CFStringRef)my_id;// Noop cast.

NSString   *c = (__bridge_transfer NSString*)my_cfref;// -1 on the CFRef

CFStringRef d = (__bridge_retained CFStringRef)my_id;// returned CFRef is +1

非ARC模式下:

[objc]view plaincopy

#pragma mark – View lifecycle

- (void)viewDidLoad

{

[superviewDidLoad];

NSLog(@"=%@", [selfescape:@"LIN986LIN"]);

}

-(NSString*)escape:(NSString*)text

{

return(NSString*)CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)text,NULL,CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));

}

ARC模式下:

可以看到xcode自动把上面函数转化为:

[objc]view plaincopy

#pragma mark – View lifecycle

- (void)viewDidLoad

{

[superviewDidLoad];

NSLog(@"=%@", [selfescape:@"wangjun"]);

}

-(NSString*)escape:(NSString*)text

{

return(__bridge_transferNSString*)CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)text,NULL,CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));

}

在arc中,CF和OC之间的转化桥梁是 __bridge,有两种方式:

__bridge_transfer  ARC接管管理内存

__bridge_retained  ARC释放内存管理

oc 到 CF 的转化,需要把OC的内存管理权释放掉。

[objc]view plaincopy

NSString*str = [[NSStringalloc]initWithFormat:@"Welcome  , %@!",name];

CFStringRef strref = (__bridge_retained CFStringRef)str;

// do something with strref

CFRelease(strref);

最后由CF进行内存释放。

上面代码等同于:

[objc]view plaincopy

CFStringRef strref = CFBridgingRetain(str);

// do something with strref

CFRelease(strref);

CF转化为OC时,并且对象的所有者发生改变,则使用CFBridgingRelease()或__bridge_transfer 。

OC转化为CF时,并且对象的所有者发生改变,则使用CFBridgingRetain()或__bridge_retained

当一个类型转化到另一种类型时,但是对象所有者没有发生改变,则使用__bridge.

CF对象和OC对象混用可能出现的问题:

ARC模式下,自动回收只针对Objective-C对象有效,对于Core Foundation对象还是需要我们手动进行释放的,CFRelease().

分析下面的情况:

在一个方法里定义了一个CGColorRef对象:CGColorRef cf

分别通过以下三种方式给cf赋值后,再使用cf时会有什么不同呢?

方式一:

[objc]view plaincopy

UIColor* color = [[UIColoralloc]initWithRed:0.0fgreen:0.0fblue:0.0falpha:1.0f];

cf = color.CGColor;

方式二:

[objc]view plaincopy

cf = [[UIColoralloc]initWithRed:0.0fgreen:0.0fblue:0.0falpha:1.0f].CGColor;

方式三:

[objc]view plaincopy

cf = [UIColorcolorWithRed:0.0fgreen:0.0fblue:0.0falpha:1.0f].CGColor;

方式一和方式三运行没问题。方式二后再使用cf会crash,因为这时cf已经是野指针了。

分析如下:

方式一中,color对象默认是strong强引用,在这个方法的生命周期内都有效,在退出这个方法时才会被自动释放池释放。所以用它的CGColor是没有问题的。

方式三中类似,colorWithRed:…这是个类方法,会返回一个autorelease对象,对象在自动释放池释放之前都有效,所以也不会出问题。

方式二中,生成的UIColor对象没有给任何owner,相当于一个weak弱引用,alloc之后被马上释放了,所以他的CGColor变量也随之成了野指针。

ARC下OC对象与CF对象桥接:

下面一行代码:

[objc]view plaincopy

CFStringRef s1= (CFStringRef)[[NSStringalloc]initWithFormat:@”Hello, %d!”,1];

在ARC下面会报编译问题,并会给出推荐的解决方案:

[objc]view plaincopy

CFStringRef s1= (__bridge CFStringRef)[[NSStringalloc]initWithFormat:@”Hello, %d!”,1];

这里NSString生成的是OC的对象,内存由ARC负责。s1是CF的对象,内存还是需要自己手动管理。两个变量转换时需要添加桥接标识。

上面这种情况下不会crash,也不会有内存泄露。因为alloc出来的内存会被ARC回收,这块内存的所有关系没变。

如果后面加上CFRelease(s1);就会crash,因为这块内存还是归ARC管的,这样会过度释放。

修改一下:

CFStringRef s1 = (__bridge_retained CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];

这种情况下,对象的所有权交给CF对象了。就需要加上CFRelease(s1);进行释放,否则会产生泄露。

再看下面代码:

[objc]view plaincopy

CFUUIDRef uu = CFUUIDCreate(NULL);

CFStringRef s2= CFUUIDCreateString(NULL, uu);

CFRelease(uu);

NSString* str = (__bridge NSString*)s2;

NSLog(@”STR:%@”,str);

CFRelease(s2);

这里的uu和s2都需要使用CFRelease释放,因为他们不是OC对象,并且是create出来的内存,并且所有权没有被释放。

如果改动下面一行代码:

NSString* str = (__bridge_transfer NSString*)s2;

这时候运行程序会引起crash,因为s2的所有权已经交给ARC中的str了,ARC会负责释放这块内存。

这时候调用CFRelease(s2);会造成过度释放。所以应该把这么行代给去了。

注:

ARC模式下,自动回收只针对Objective-C对象有效,对于使用create,copy,retain等生成的Core Foundation对象还是需要我们手动进行释放的,CFRelease().


由于iOS中CF框架需要自己释放内存,所以ARC的自动释放内存就不管用了,需要我们自己释放,需要使用CFRelease(<#CFTypeRef cf#>)这个方法来手动释放内存.

一:  ARC模式:NSLog(@”Retain count is %ld”, CFGetRetainCount((__bridge CFTypeRef)myObject));

二 : CF框架:NSLog(@”Retain count is %ld”, CFGetRetainCount(myObject));

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,858评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,372评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,282评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,842评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,857评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,679评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,406评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,311评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,767评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,090评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,785评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,420评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,988评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,101评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,298评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,033评论 2 355

推荐阅读更多精彩内容