iOS开发之Xcode的静态分析(Static Code Analysis)与常见问题解决
一.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')
错误:
Crayon Syntax Highlighter v_2.7.2_beta
-(UIView*)test
{
CGRect rect;
UIView *view = [[UIView alloc]init];
view.frame = rect;
return view;
}
1 2 3 4 5 6 7 | -(UIView*)test { CGRect rect; UIView *view = [[UIView alloc]init]; view.frame = rect; return view; } |
[Format Time: 0.0018 seconds]
正确:
Crayon Syntax Highlighter v_2.7.2_beta
-(UIView*)test
{
CGRect rect = CGRectZero;
UIView *view = [[UIView alloc]init];
view.frame = rect;
return view;
}
1 2 3 4 5 6 7 | -(UIView*)test { CGRect rect = CGRectZero; UIView *view = [[UIView alloc]init]; view.frame = rect; return view; } |
[Format Time: 0.0019 seconds]
2.Value stored to 'array' during its initialization is never read
变量申请了内存并初始化,但没有使用此变量,接着将此变量又重新赋值
错误:
Crayon Syntax Highlighter v_2.7.2_beta
NSMutableArray *array = [NSMutableArray array];
array = [responseObject objectForKey:@"result"];
.....
1 2 3 | NSMutableArray *array = [NSMutableArray array]; array = [responseObject objectForKey:@"result"]; ..... |
[Format Time: 0.0013 seconds]
正确:
Crayon Syntax Highlighter v_2.7.2_beta
NSMutableArray *array = [responseObject objectForKey:@"result"];
.....
1 2 | NSMutableArray *array = [responseObject objectForKey:@"result"]; ..... |
[Format Time: 0.0010 seconds]
3.Value stored to 'array' is never read
变量'array' 未被使用
Crayon Syntax Highlighter v_2.7.2_beta
__unused NSMutableArray *array = @[@"1",@"2"]; //使用__unused或者注释掉
1 | __unused NSMutableArray *array = @[@"1",@"2"]; //使用__unused或者注释掉 |
[Format Time: 0.0009 seconds]
4. The 'viewWillAppear:' instance method in UIViewController subclass 'TempViewController' is missing a [super viewWillAppear:] call
错误
Crayon Syntax Highlighter v_2.7.2_beta
-(void)viewWillAppear:(BOOL)animated{
....
}
1 2 3 | -(void)viewWillAppear:(BOOL)animated{ .... } |
[Format Time: 0.0009 seconds]
正确
Crayon Syntax Highlighter v_2.7.2_beta
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
.....
}
1 2 3 4 | -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; ..... } |
[Format Time: 0.0012 seconds]
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...]'
错误
Crayon Syntax Highlighter v_2.7.2_beta
-(id)init
{
if(![super init]){
return nil;
}
return self;
}
1 2 3 4 5 6 7 | -(id)init { if(![super init]){ return nil; } return self; } |
[Format Time: 0.0014 seconds]
正确
Crayon Syntax Highlighter v_2.7.2_beta
-(id)init
{
self = [super init];
if(!self){
return nil;
}
return self;
}
1 2 3 4 5 6 7 8 | -(id)init { self = [super init]; if(!self){ return nil; } return self; } |
[Format Time: 0.0016 seconds]
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不能为nil
14.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
变量未进行初始化后被其他变量引用
错误
Crayon Syntax Highlighter v_2.7.2_beta
-(UIView*)test
{
CGRect rect;
CGSize size;
CGRect rectResult = CGRectMake(rect.origin.x, rect.origin.y, size.width, size.height);
UIView *view = [[UIView alloc]initWithFrame:rectResult];
return view;
}
1 2 3 4 5 6 7 8 | -(UIView*)test { CGRect rect; CGSize size; CGRect rectResult = CGRectMake(rect.origin.x, rect.origin.y, size.width, size.height); UIView *view = [[UIView alloc]initWithFrame:rectResult]; return view; } |
[Format Time: 0.0046 seconds]
正确
Crayon Syntax Highlighter v_2.7.2_beta
-(UIView*)test
{
CGRect rect = CGRectZero;
CGSize size = CGSizeZero;
CGRect rectResult = CGRectMake(rect.origin.x, rect.origin.y, size.width, size.height);
UIView *view = [[UIView alloc]initWithFrame:rectResult];
return view;
}
1 2 3 4 5 6 7 8 | -(UIView*)test { CGRect rect = CGRectZero; CGSize size = CGSizeZero; CGRect rectResult = CGRectMake(rect.origin.x, rect.origin.y, size.width, size.height); UIView *view = [[UIView alloc]initWithFrame:rectResult]; return view; } |
[Format Time: 0.0053 seconds]
19.Division by zero
错误
Crayon Syntax Highlighter v_2.7.2_beta
NSUInteger measurements = [bandwidthUsageTracker count];
unsigned long totalBytes = 0;
for (NSNumber *bytes in bandwidthUsageTracker) {
totalBytes += [bytes unsignedLongValue];
}
averageBandwidthUsedPerSecond = totalBytes/measurements;
1 2 3 4 5 6 | NSUInteger measurements = [bandwidthUsageTracker count]; unsigned long totalBytes = 0; for (NSNumber *bytes in bandwidthUsageTracker) { totalBytes += [bytes unsignedLongValue]; } averageBandwidthUsedPerSecond = totalBytes/measurements; |
[Format Time: 0.0022 seconds]
正确 加个非零判断
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
参数可能为nil
Crayon Syntax Highlighter v_2.7.2_beta
NSCharacterSet *cs;
if (textField == _text1) {
cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
} else if (textField == _text2) {
cs = [[NSCharacterSet characterSetWithCharactersInString:SIGNLESS_NUMBERS] invertedSet];
}
NSArray *array = [string componentsSeparatedByCharactersInSet:cs];
1 2 3 4 5 6 7 | NSCharacterSet *cs; if (textField == _text1) { cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet]; } else if (textField == _text2) { cs = [[NSCharacterSet characterSetWithCharactersInString:SIGNLESS_NUMBERS] invertedSet]; } NSArray *array = [string componentsSeparatedByCharactersInSet:cs]; |
[Format Time: 0.0029 seconds]