2011-04-20 133 views
1

我的內存管理應用程序出現問題。有一些我不明白的概念。例如,這個代碼有什麼問題?我應該如何處理這個問題?iPhone內存管理

CustomController.h:

@interface CustomController : UIViewController <UIScrollViewDelegate> 
{  
    IBOutlet UIScrollView *scroll_view; 
} 

@property (nonatomic, retain) UIScrollView *scroll_view; 

@end 

CustomController.m:

@implementation CustomController 

@synthesize scroll_view; 

- (void)viewDidLoad 
{ 
    [self setup_content]; 
    [super viewDidLoad]; 
} 

- (void) setup_content 
{ 
    // Fill the scrollview with some subviews 
} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)viewDidUnload 
{ 
    [scroll_view release]; 
    scroll_view = nil; 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)dealloc 
{  
    [scroll_view release]; 
    [super   dealloc]; 
} 

@end 

使用它:

CustomController *custom_controller = [[CustomController alloc] initWithNibName: @"CustomController" bundle: nil]; 
NSLog(@"Controller: %i", [custom_controller retainCount]); 
NSLog(@"ScrollView: %i", [custom_controller.scroll_view retainCount]); 

[controllersArray addObject: custom_controller]; 
NSLog(@"Controller: %i", [custom_controller retainCount]); 
NSLog(@"ScrollView: %i", [custom_controller.scroll_view retainCount]); 

[custom_controller release]; 
NSLog(@"Controller: %i", [custom_controller retainCount]); 
NSLog(@"ScrollView: %i", [custom_controller.scroll_view retainCount]); 

和輸出:

Controller: 1 
ScrollView: 0 

Controller: 2 
ScrollView: 2 

Controller: 1 
ScrollView: 2 

在這一點上,當我從數組中刪除控制器,因爲我不再需要它了,scrollView在控制器的dealloc方法中的retainCount是2,並且內存沒有被釋放(scrollView有很多未被存儲的uiimageviews發佈)。有人可以幫忙嗎?

編輯:

最後的問題是,控制器視圖正在由導航控制器保留。我正在使用控制器陣列作爲自定義導航的堆棧。在彈出窗口中,我從陣列中移除了控制器,但導航控制器仍然保留了該視圖。從超級視圖中刪除它可以解決問題,現在我的scrollView和它擁有的所有子視圖都可以正確釋放!謝謝大家!

+3

不要調用** retainCount **。這對於調試這種東西來說是無用的。 – bbum 2011-04-20 16:07:38

回答

0

IBOutlet的私有變量名爲scroll_view,而該屬性名爲m_scroll_view。

然後,你將需要告訴@@合成的屬性應使用正確的私有變量:

@synthesize m_scroll_view = scroll_view; 

(編輯刪除此)

你也應該首先調用之前的任何超級方法調用你自己的,除非調用dealloc。

0
@interface CustomController : UIViewController <UIScrollViewDelegate> 
{  
    IBOutlet UIScrollView *scroll_view; 
} 

@property (nonatomic, retain) UIScrollView *scroll_view; 

它的善良有另一個名稱爲ivar比屬性例如_scroll_view,這樣你可以看到哪個是哪個。通常,在處理屬性時使用self.property,使其更易於查看其屬性,並在使用iviv時使用_ivar。

@interface CustomController : UIViewController <UIScrollViewDelegate> 
{  
    IBOutlet UIScrollView *_scroll_view; 
} 

@property (nonatomic, retain) UIScrollView *scroll_view = _scroll_view; 
+0

感謝您的建議,我將在我的代碼上進行更改。瞭解最佳實踐總是很好的。 – zartako 2011-04-20 16:09:47

0

你的測試代碼並不顯示發生了什麼之後,你還從陣列中刪除。在這種情況下,控制器上的保留計數應該爲0,滾動視圖應該爲1.我懷疑scrollview仍然有一個保留計數的原因是它仍然在視圖層次結構中被引用。如果你刪除了視圖,它應該被解除分配。

您還可以在滾動視圖的保留消息中添加一個斷點,以查看誰在保留它並確保它們也釋放它。

+0

謝謝,正如您指出的那樣,滾動似乎正在層次結構中被引用。我即將採取這種方式。 – zartako 2011-04-20 17:20:45

0

controllersArray仍然持有您的custom_controller這就是保留計數是1. 當您從陣列中刪除該對象時,它應該下降到0,然後滾動器將被釋放。

所以你應該嘗試[controllersArray removeObject:custom_controller]當你完成它。 假設controllersArray當然是NSMutableArray。

+0

謝謝,當我從數組中移除它並調用dealloc方法時,CustomController被正確釋放。問題是在發佈後有一個retainCount的scrollView。 – zartako 2011-04-20 17:18:34

+0

可以從程序中的其他地方保留scrollView嗎? – 2011-04-21 15:00:31

+0

U也可能會覆蓋保留方法以進行測試和調試,以查看誰在調用它。這樣你可以看到其他對象是否保留了你的scrollView。在上面的代碼中可能沒有顯示的另一件事可能是你放在你的滾動視圖上的一個視圖也保留着它。儘量不要放任何東西,看看它是否被髮布,那麼你就會知道它是它的一個子視圖 – 2011-04-21 15:02:56