在Objc的MRC(手动引用计数)内存管理时, 使用引用计数来维护内存的回收,引用计数的错误常常导致内存泄漏。有一个很常见的错误就是一个retain的属性或成员没有在dealloc中释放。而这种错误用静态代码分析工具检测不出来。当代码写的很多时,一个类一个类的检查很麻烦,而且容易疏露。我写了一个自动检查这种错误的小工具(occheck)。另外这个工具还能检查代码中的高危函数。
安装occheck(有些同学反馈command not fond的解决方法):
occheck是个二进制命令行工具,拷贝到/usr/bin目录下才可以直接在终端中输入使用。
sudo cp /path/to/occheck /usr/bin/occheck sudo chmod -R 755 /usr/bin/occheck
使用方法:
occheck [-arc] [path] ...
[path]是要检查代码所在的目录,可以是你的工程目录。运行之后会自动检查path目录下的所有objc文件。自动检测类的retain成员,如果忘记在dealloc中release相关成员就会输出错误。
如果你的项目使用ARC,可以不检查内存泄漏,指定”-arc”参数将只检查高危函数。
如:
occheck /Users/brightshen/Documents/elife/trunk/ios/QQGroupon
输出:
ERROR: QHTTPCacheManager cacheRootPath 没有在dealloc中release.
ERROR: CategoryView buttons 没有在dealloc中release.
ERROR: TodayDealListViewController dealInfosThisRounds 没有在dealloc中release.
ERROR: TodayDealListViewController dealInfosThisRound 没有在dealloc中release.
可以强制指定一个类成员为assign而不是retain
只需要在变量类型前面加入ASSIGN
比如:
#define ASSIGN
@interface QPicker : UIView{
NSArray *items;
UIPickerView *pickerView;
UIToolbar *toolBar;
UIView *coverView;
ASSIGN id<QPickerDelegate>delegate;
id userInfo;
}
@end
这样就不会把delegate作为一个retain的成员来处理。如果delegate在属性中定义为assign,那么前面的ASSIGN可以不加,会自动检测。
也可以设置一个类是单例的,这样就不会检查dealloc了,只需要在类的名字前面加上SINGLETON
#define SINGLETON
@interface SINGLETON QQTicketAppDelegate : NSObject <UIApplicationDelegate,UIAlertViewDelegate> {
QTTabBarController *tabBarController;
UIViewController *movieViewController;
UIViewController *cinemaViewController;
UIViewController *myViewController;
UIViewController *moreViewController;
UIWindow *window;
UILocalNotification *movieNotification;
}
@end
项目地址:https://github.com/shenqiliang/occheck