在Objc的MRC(手动引用计数)内存管理时, 使用引用计数来维护内存的回收,引用计数的错误常常导致内存泄漏。有一个很常见的错误就是一个retain的属性或成员没有在dealloc中释放。而这种错误用静态代码分析工具检测不出来。当代码写的很多时,一个类一个类的检查很麻烦,而且容易疏露。我写了一个自动检查这种错误的小工具(occheck)。另外这个工具还能检查代码中的高危函数。
使用方法:
1
|
occheck [-arc] [path] ...
|
[path]是要检查代码所在的目录,可以是你的工程目录。运行之后会自动检查path目录下的所有objc文件。自动检测类的retain成员,如果忘记在dealloc中release相关成员就会输出错误。
如果你的项目使用ARC,可以不检查内存泄漏,指定”-arc”参数将只检查高危函数。
如:
1
|
occheck
/Users/brightshen/Documents/elife/trunk/ios/QQGroupon
|
输出:
1
2
3
4
|
ERROR: QHTTPCacheManager cacheRootPath 没有在dealloc中release.
ERROR: CategoryView buttons 没有在dealloc中release.
ERROR: TodayDealListViewController dealInfosThisRounds 没有在dealloc中release.
ERROR: TodayDealListViewController dealInfosThisRound 没有在dealloc中release.
|
可以强制指定一个类成员为assign而不是retain
只需要在变量类型前面加入ASSIGN
比如:
1
2
3
4
5
6
7
8
9
10
|
#define ASSIGN
@interface
QPicker :
UIView
{
NSArray
*
items
;
UIPickerView
*
pickerView
;
UIToolbar
*
toolBar
;
UIView
*
coverView
;
ASSIGN
id
&
lt
;QPickerDelegate&
gt
;
delegate
;
id
userInfo
;
}
@end
|
这样就不会把delegate作为一个retain的成员来处理。如果delegate在属性中定义为assign,那么前面的ASSIGN可以不加,会自动检测。
也可以设置一个类是单例的,这样就不会检查dealloc了,只需要在类的名字前面加上SINGLETON
1
2
3
4
5
6
7
8
9
10
11
|
#define SINGLETON
@interface
SINGLETON QQTicketAppDelegate :
NSObject
&
lt
;
UIApplicationDelegate
,
UIAlertViewDelegate
&
gt
; {
QTTabBarController *
tabBarController
;
UIViewController
*
movieViewController
;
UIViewController
*
cinemaViewController
;
UIViewController
*
myViewController
;
UIViewController
*
moreViewController
;
UIWindow
*
window
;
UILocalNotification
*
movieNotification
;
}
@end
|