2011-04-20 138 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