可以在这个例子中解释代码流吗?内存泄漏?哪里?

时间:2011-03-01 16:47:29

标签: iphone objective-c memory-management ios4

参考这个PageControl示例有人可以解释一下代码流吗?仪器正在给我泄漏,所以寻求一些帮助。

Re:本教程: http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/

我们在AppDidFinishLaunching方法中将数组初始化为Null对象......

NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
    [controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];

然后致电:

[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];

以下是 loadScrollViewWithPage 的实现:

- (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= kNumberOfPages) return;

PageControlExampleViewControl *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
    controller = [[PageControlExampleViewControl alloc] initWithPageNumber:page];
    [viewControllers replaceObjectAtIndex:page withObject:controller];
    [controller release];
}

if (nil == controller.view.superview) {
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    controller.view.frame = frame;
    [scrollView addSubview:controller.view];
}
}

仪器在以下行中泄漏了这个实现:

if(nil == controller.view.superview){

任何人都知道为什么这会是仪器报告的漏洞?我的代码完全相同。 在初始调用 [self loadScrollViewWithPage:0]; 之后,在第一次传递并创建对象时, BOTH 如果传递,则输入

这怎么可能? 如果我们输入第一个 if子句,我们分配并创建我们的控制器并以**释放* it( [controller release] )结束。

下一行( if(nil == controller.view.superview))是否应该产生EXC_BAD_ACCESS错误,因为我们只是在上面发布了 controller

来自乐器的屏幕截图: Instruments screenshot

3 个答案:

答案 0 :(得分:1)

我不知道为什么Instruments会报告该行的泄漏,除非它只是注意到该行分配了controller.view(如果需要,访问UIViewController的view属性会自动加载视图)并且尚未释放(只要scrollView存在并且controller.view仍然是它的子视图,它就不应该这样。)

它通过两个if条款是正确的。第一个if检查视图控制器是否实际存在该页面索引,如果不存在则创建一个(但将其添加到scrollView)。第二个检查是否已将页面索引的视图控制器视图添加到scrollView,如果没有,则添加它。

它不崩溃的原因是因为[viewControllers replaceObjectAtIndex:page withObject:controller]将控制器添加到NSMutableArray,后者保留了控制器。这样做可能会稍微有些混乱:

if ((NSNull *)controller == [NSNull null]) {
    controller = [[[PageControlExampleViewControl alloc] initWithPageNumber:page] autorelease];
    [viewControllers replaceObjectAtIndex:page withObject:controller];
}

答案 1 :(得分:0)

在我看来,你没有正确发布scrollView。

答案 2 :(得分:0)

  

这怎么可能?如果我们输入第一个if子句,我们分配并创建我们的控制器并以*释放它([控制器发布])。

     

不应该下一行(if(nil == controller.view.superview))产生EXC_BAD_ACCESS错误,因为我们刚刚发布RELEASED控制器吗?

查看alloc和release之间的界限。

[viewControllers replaceObjectAtIndex:page withObject:controller];

viewControllers数组将保留控制器。

但是这不是好的代码。正是因为你说的原因。乍一看不太清楚。