Possible to explain code flow in this example ?? Memory leak? Where?
Referring to this PageControl example could somebody please explain the code flow? Instruments is giving me a leak here so looking for some help.
Re: this tutorial: http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/
We init an array to Null objects in our AppDidFinishLaunching method...
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
and then call:
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
Here is the implementation for 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];
}
}
Instruments is giving me a leak in this implementation on the following line:
if (nil == controller.view.superview) {
Anyone know why this would be a reported leak in Instruments? My code is identical. Also after the initial call [self loadScrollViewWithPage:0];, on the first pass through and creating the object, BOTH if clauses are passed and entered.
How is this possible? If we enter the first if clause, we alloc and create our controller and end by **releasing* it ([controller release]).
Shouldn't the next line (if (nil == controller.view.superview)) produce an EXC_BAD_ACCESS error seeing as we just RELEASED controller above?
开发者_如何学GoSCREENSHOT FROM INSTRUMENTS:
I don't know why Instruments would be reporting a leak on that line, unless it's just noticing that controller.view was allocated by that line (accessing a UIViewController's view property automatically loads the view if necessary) and not yet freed (which it shouldn't be as long as scrollView exists and controller.view remains as a subview of it).
It is correct that it goes through both if
clauses. The first if
checks whether a view controller actually exists for that page index, and if not it creates one (but does not add it to the scrollView). The second checks if the view for the view controller for the page index has already been added to the scrollView, and if not it adds it.
The reason it does not crash is because [viewControllers replaceObjectAtIndex:page withObject:controller]
adds the controller to an NSMutableArray, which retains the controller. It might be slightly less confusing to do it like this instead:
if ((NSNull *)controller == [NSNull null]) {
controller = [[[PageControlExampleViewControl alloc] initWithPageNumber:page] autorelease];
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
It seems to me that you are not properly releasing the scrollView.
How is this possible? If we enter the first if clause, we alloc and create our controller and end by *releasing it ([controller release]).
Shouldn't the next line (if (nil == controller.view.superview)) produce an EXC_BAD_ACCESS error seeing as we just RELEASED controller above?
look at the line between alloc and release.
[viewControllers replaceObjectAtIndex:page withObject:controller];
the viewControllers array will retain the controller.
But imho it's no good code. for exactly the reason you've stated. Not very clear at first sight.
精彩评论