前些日子在項目中因為誤用了單例而導致了一系列問題。原來在objective-c中的單例並沒有java或者C#那麼簡單的實現,這裡記錄下;
問題是這樣被發現的,在對於一個UIViewController進行pop時並沒有被dealloc,導致了內存洩露。問題代碼類似於下面的:
- //LWChatViewController.h
- @interface LWChatViewController : LWTableViewController <LWObjSelectViewDelegate>{
- UINavigationController *root;
- }
- @property (nonatomic, retain) UINavigationController *root;
- @end
-
- //LWChatViewController.m
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
- self.root = LWNavigationController;
- }
這裡的LWNavigationController是一個頂級的單例。
問題就出在@property (nonatomic, retain) 這裡root居然是一個retain的對象指針,在這裡retain一個static的單例將導致內存洩露,MD,這個bug找的我好久。。。
解決這個問題其實很簡單,把retain改為assign就行了,但這樣如果在協作編程的時候如果別人不在意這個是單例直接進行常規操作的話會帶來很大的問題。
繼續,我們來從根本上解決這個問題。
我們需要重寫一些方法:
- - (id)retain
- {
- return self;
- }
-
- - (NSUInteger) retainCount
- {
- return NSUIntegerMax;
- }
-
- - (void) release
- {
- // do nothing
- }
-
- - (id)autorelease
- {
- return self;
- }