Reputation: 484
I've been scratching my head for a long time now, trying to solve this problem. I've searched StackOverflow, and have found people asking for something that resembles my problem like this question and this question, but none of the answers given have helped me.
To explain the problem in detail:
I've used Apple's Paging example to enable paging between view controllers
The View hierachy is as follows: UIWindow -> UIScrollView (MainController) -> UIViewControllers.
I use this code to create a delegate to the Viewcontroller containing the UISCrollview:
if(page == 0)
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
controller = [[ContractsViewController alloc] initWithNibName:@"ContractsView" bundle:nil];
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
controller.view.tag = 0;
[scrollView addSubview:controller.view];
}
}
The problem then occurs, when I try to present a modalviewcontroller from my ViewController inside the scrollview using the delegate. It works a few times, but then gives me a EXC_BAD_ACCESS. I've also tried posting a notification, and creating a listener in the MainController, to present it that way, but still the same problem.
When testing in iOS 4.3 everything works like a charm, but in iOS5 I get the issue.
I hope someone can help me get rid of this issue.
Thank you in advance.
Upvotes: 2
Views: 1318
Reputation: 484
As a start thank you for all your answers! I've finally found the solution to the problem.
As mentioned in my question, I used Apple's Pagecontrol sample as a template for my project. This template has a rootViewController which has an XIB with a window containing an UIScrollview and a Pagecontrol.
The problem happened, when I was trying to present the ModalView from a UIViewController inside the scrollview. I wanted to use the delegate, to present it through the rootViewController, but found out that it was using the UIScrollview to present it.
The UIScrollView object was apperently not retained, so after a couple of dismisses I hit the EXC_BAD_ACCESS.
I then figured, that i needed an UIView in the rootViewController, and placed it in the bottom viewhierachy in the XIB, and connected it with the view of the rootViewController. After I did that, I could use [delegate present..] and [delegate dismiss..] in the UIViewController without the EXC_BAD_ACCESS.
Yay! :)
Upvotes: 1
Reputation: 86651
Try running the code with NSZombiesEnabled.
My guess is that the viewControllers object is either never initialised or is being released prematurely.
Also, there's this if (page == 0)
wierdness:
if(page == 0) // <== only the first page ever gets the init code calling
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
// ** SNIP **
[viewControllers replaceObjectAtIndex:page // <<=== always 0
withObject:controller];
[controller release];
}
// ** SNIP **
}
Upvotes: 0
Reputation: 12405
I think I see your problem.. in the first if you release controller
object and then you try to use it in the second if loop because of which you recieve this. release the controller object after both the if loops have passed.
EDIT:
try this code instead..
if(page == 0)
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
controller = [[[ContractsViewController alloc] initWithNibName:@"ContractsView" bundle:nil]autorelease];
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
controller.view.tag = 0;
[scrollView addSubview:controller.view];
}
}
Upvotes: 0
Reputation: 3824
I suggest removing your [controller release];
and adding an autorelease: controller = [[[ContractsViewController alloc] initWithNibName:@"ContractsView" bundle:nil] autorelease];
You don't own controller
when it's returned from objectAtIndex:
, so that way you could have the same behavior for both controllers, no releases.
Upvotes: 0