iOS开发之Xcode的静态分析(Static Code Analysis)与常见问题解决
StaticCodeAnalysis...
一.Xcode Analyze静态分析 Static Code Analysis
Static Code Analysis(静态代码分析)用来发现源代码潜在的错误与缺陷,源代码编译后只有在运行时有可能会产生细微的错误,他们可能难以识别和修复,所以这些潜在的威胁在开发过程中一定要尽可能清理干净,尽量编写的时候注意类似可能潜在的威胁与缺陷(点击查看苹果Static Code Analysis官方介绍)
二.可以识别的问题与缺陷
1.逻辑缺陷,如访问未初始化的变量和空指针2.内存管理的缺陷,如分配后的内存泄漏
3.无效数据(未使用的变量)缺陷
4.使用api缺陷,不遵循库或者框架的使用规则
三.打开方式
1.Xcode顶部菜单Product-->Analyze即可开启2.长按Xcode的run运行箭头选择Analyze即可开启
3.cmd + shift + b 快捷键开启
四.使用方法
1.左侧问题导航选择某一条蓝色警告分析2.点击右侧源码编辑器的蓝色消息体
3.查看错误跟踪线
4.编辑代码修改错误
五.常见问题缺陷与解决办法
1.Passed-by-value struct argument contains uninitialized data (e.g., via the field chain: 'origin.x')
错误:1
2
3
4
5
6
7
-(UIView*)test
{
CGRectrect;
UIView*view=[[UIViewalloc]init];
view.frame=rect;
returnview;
}
正确:
1
2
3
4
5
6
7
-(UIView*)test
{
CGRectrect=CGRectZero;
UIView*view=[[UIViewalloc]init];
view.frame=rect;
returnview;
}
2.Value stored to 'array' during its initialization is never read
变量申请了内存并初始化,但没有使用此变量,接着将此变量又重新赋值错误:
1
2
3
NSMutableArray*array=[NSMutableArrayarray];
array=[responseObject objectForKey:@"result"];
.....
正确:
1
2
NSMutableArray*array=[responseObject objectForKey:@"result"];
.....
3.Value stored to 'array' is never read
变量'array' 未被使用
1
__unused NSMutableArray*array=@[@"1",@"2"]; //使用__unused或者注释掉
4. The 'viewWillAppear:' instance method in UIViewController subclass 'TempViewController' is missing a [super viewWillAppear:] call
错误1
2
3
-(void)viewWillAppear:(BOOL)animated{
....
}
正确
1
2
3
4
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
.....
}
5.Assigned value is garbage or undefined
变量没有初始化就赋值给其他变量时会出现这个提示6.Access to instance variable 'viewDelegate' results in a dereference of a null pointer (loaded from variable 'self')
如果self是nil,那么你不能访问self的实例变量 。所以应该引用这些变量在if self语句中,比如init方法中 当self不为nil方可使用7.Potential leak of an object stored into 'imageRef'
CGImageRelease(imageRef)CG开头的这些C-types对象使用过后都需要手动Release
8.Potential leak of an object
潜在的内存泄漏问题9.Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected
10.Instance variable used while 'self' is not set to the result of '[(super or self) init...]'
错误1
2
3
4
5
6
7
-(id)init
{
if(![superinit]){
returnnil;
}
returnself;
}
正确
1
2
3
4
5
6
7
8
-(id)init
{
self=[superinit];
if(!self){
returnnil;
}
returnself;
}
11.The left operand of '+' is a garbage value /The left operand of '-' is a garbage value
数据赋值隐患12.Instance variable 'program' in class 'PLRenderer' is never used by the methods in its @implementation (although it may be used by category methods)
13.Key argument to 'setObject:forKey:' cannot be nil/Value argument to 'setObject:forKey:' cannot be nil
key或者value不能为nil14.Incorrect decrement of the reference count of an object that is not owned at this point by the caller
变量申请了内存并初始化,但没有使用此变量,接着将此变量又重新赋值15.Array access (from variable 's') results in a null pointer dereference
16.Dereference of null pointer
空指针引用17.Argument in message expression is an uninitialized value
18.Function call argument is an uninitialized value
变量未进行初始化后被其他变量引用错误
1
2
3
4
5
6
7
8
-(UIView*)test
{
CGRectrect;
CGSizesize;
CGRectrectResult=CGRectMake(rect.origin.x,rect.origin.y,size.width,size.height);
UIView*view=[[UIViewalloc]initWithFrame:rectResult];
returnview;
}
正确
1
2
3
4
5
6
7
8
-(UIView*)test
{
CGRectrect=CGRectZero;
CGSizesize=CGSizeZero;
CGRectrectResult=CGRectMake(rect.origin.x,rect.origin.y,size.width,size.height);
UIView*view=[[UIViewalloc]initWithFrame:rectResult];
returnview;
}
19.Division by zero
错误1
2
3
4
5
6
NSUIntegermeasurements=[bandwidthUsageTracker count];
unsignedlongtotalBytes=0;
for(NSNumber*bytesinbandwidthUsageTracker){
totalBytes+=[bytes unsignedLongValue];
}
averageBandwidthUsedPerSecond=totalBytes/measurements;
正确 加个非零判断
20.Receiver in message expression is a garbage value
要回收的变量接受到了消息21.Argument to free() is offset by 2 bytes from the start of memory allocated by malloc()
22.Argument to 'NSString' method 'componentsSeparatedByCharactersInSet:' cannot be nil
参数可能为nil1
2
3
4
5
6
7
NSCharacterSet*cs;
if(textField==_text1){
cs=[[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
}elseif(textField==_text2){
cs=[[NSCharacterSet characterSetWithCharactersInString:SIGNLESS_NUMBERS] invertedSet];
}
NSArray*array=[string componentsSeparatedByCharactersInSet:cs];
欢迎打赏
转载自原文地址;
关注 代码猿
微信扫一扫关注公众号