I have a UITableView inside a UITabBarController.
When I'm calling
[[self navigationController] pushViewController:myViewController animated:YES];
there is no problem.
But, when I'm calling the same line from inside a UIActionSheetDelegate, for example:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
I get EXC_BAD_ACCESS.
It seems that calling this line from a different thread causing this issue.
How can I prevent this EXC_BAD_ACCESS issue?
(notice that myViewController is NOT nil, or something like that)
thanks!
EXC_BAD_ACCESS is thrown when you try to access a released object, and actionSheet:clickedButtonAtIndex: is called on the main thread, after the action sheet is dismissed, so I'm guessing what's pointed by myViewController is released.
It doesn't have to be nil, in fact, that's the problem. The object pointed is released, but the pointer is not nil.
I just had the same problem and mine was that I did not assine the member varible with self when I alloced it.
This causeed a problem: (myTestViewController is the class member)
TestViewController* test = [[TestViewController alloc] init];
myTestViewController = testViewController;
[testViewController release];
[[self navigationController] pushViewController:myTestViewController animated:YES];
But when I change and assied the class member with self it worked.
TestViewController* test = [[TestViewController alloc] init];
self.myTestViewController = testViewController;
[testViewController release];
[[self navigationController] pushViewController:myTestViewController animated:YES];
I had a similar problem. The way I fixed it was by removing self.navigationController.delegate = self; from my pushed view controller.
tnx.
The UIActionSheet is called from within a class called: MainRootViewController
myViewController is a member in this class (MainRootViewController).
The full code is:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
myViewController = [[myViewController alloc] init];
[[self navigationController] pushViewController:myViewController animated:YES];
}
Related
I have LoginViewControllerIphone instance , where I push the instance of TasksRootViewControllerIphone
then in TasksRootViewControllerIphone (10 seconds after appearing) I call [self.navigationController popViewControllerAnimated:YES];
And receive an error:
[NSRecursiveLock isSystemItem]: unrecognized selector sent to instance 0x3ba360
I tried to print navigation controller stack:
po [self.navigationController viewControllers]
$2 = 0x003445f0 <__NSArrayI 0x3445f0>(
<LoginViewControllerIphone: 0x3b73c0>,
<TasksRootViewControllerIphone: 0x3af290>
)
So it has proper view controllers. Any ideas how can it happen?
update:
pushing code:
self.tasksRootViewControllerIphone = [[TasksRootViewControllerIphone alloc] initWithNibName:#"TasksRootViewControllerIphone" bundle:nil];
self.tasksRootViewControllerIphone.view.backgroundColor = [UIColor clearColor];
[self.loginViewControllerIphone.navigationController pushViewController:self.tasksRootViewControllerIphone animated:YES];
in TasksRootViewControllerIphone.m I have:
- (void)viewDidLoad
{
[self performSelector:#selector(popCurrentViewControllerAnimated) withObject:self afterDelay:10];
}
- (void)popCurrentViewControllerAnimated
{
[self.navigationController popViewControllerAnimated:YES];
}
Update your viewDidload Method as
- (void)viewDidLoad
{
[self performSelector:#selector(popCurrentViewControllerAnimated) withObject:nil afterDelay:10];
}
hopefully it solve your problem.
As the method popCurrentViewControllerAnimated not take any argument. so withObject should be nil. not self.
I found the point.
The problem was because it's not arc project, and one of the UIBarButtonItems was released one time more.
Strange, but it caused the problem with popViewController.
I want to call this method:
- (void)getUserFriendTargetDialogRequest {
currentAPICall = kAPIFriendsForTargetDialogRequests;
[self apiGraphFriends];
}
from this conditional statement that's in another viewcontroller:
if (idx == 2) {
NSLog(#"you touched menu 2");
APICallsViewController *apiViewController = [APICallsViewController alloc];
[self.navigationController pushViewController:apiViewController animated:YES];
}
can anyone help with the syntax on this?
thanks so much
First, you probably also want to init your APICallsViewController via:
APICallsViewController *apiViewController = [[APICallsViewController alloc] initWithNibName:nil bundle:nil];
Then if that getUserFriend... is a method of APIViewController, you can do this:
[apiViewController getUserFriendTargetDialogRequest];
However, since you aren't passing any arguments in from your other view controller, you might consider calling it in the init method, or the viewDidLoad method of APICallsViewController.
OtherViewController *viewController = [[OtherViewController alloc]
init];
[viewController methodName];
[viewController release];
1>Just alloc the class in which the method is and then call it through object of that class.
ViewControllWithMethod *view=[ViewControllWithMethod alloc]]init];
[view getUserFriendTargetDialogRequest];
2>Instead of instance method you can make it as class method then you will be able to call it through className.getUserFriendTargetDialogRequest
I would like to know a method for navigating from one page to another page onclick .I
have tried
[self.navigationController
pushViewController:self
.objectNewlist
animated:YES];
but it is showing the error
Incompatible pointer types sending 'newlistplist *' to parameter of type 'UIViewController *'
my main class file is a subclass of UIViewController
and the second class is a subclass of UITableViewController
can any one help me out with this problem?
You can use
UIViewController *yourViewController = [[YourViewControllerClass alloc] initWithNibName:#"<name of xib>" bundle:nil];
[self presentModalViewController:yourViewController animated:YES];
[yourViewController release];
In case the new view is also to be created programmatically, you can do that in the viewDidLoad method of YourViewControllerClass and change the initialization to
UIViewController *yourViewController = [[YourViewControllerClass alloc] init];
In YourViewController when you wish to come back to previous view on some button action you can use
[self dismissModalViewControllerAnimated:YES];
Another way that you can do is
UIViewController *yourViewController = [[YourViewControllerClass alloc] init];
[self addSubview:[yourViewController view]];
and to remove the view you can use
[self.view removeFromSuperview];
-(void)onClickButton
{
ViewControllerClass *objViewControllerClass = [ViewControllerClass alloc] init] ;
[self presentModalViewController:objViewControllerClass animated:YES];
[objViewControllerClass release];
}
objViewControllerClass (object of another class)
I'm developing an iPhone 3.1.3 app with iOS 4 SDK.
I have two ViewControllers, mainViewController and AboutViewController.
I use this code to go from mainViewController to AboutViewController (code inside mainViewController.m):
- (IBAction) aboutClicked:(id)sender
{
AboutViewController* aboutController =
[[AboutViewController alloc]
initWithNibName:#"AboutViewController"
bundle:nil];
[self.view addSubview:aboutController.view];
[aboutController release];
}
And this to come back from AboutViewController to mainViewController (code inside AboutViewController.m):
- (IBAction) backClicked:(id) sender
{
[self.view removeFromSuperview];
}
When I click on Back Button on AboutViewController, I get an EXC_BAD_ACCESS.
I'm using a window-based application template.
I've also tried to add a breakpoint in [self.view removeFromSuperview] but I can't.
Do you know why?
Do this instead:
- (IBAction) aboutClicked:(id)sender
{
AboutViewController* aboutController =
[[AboutViewController alloc]
initWithNibName:#"AboutViewController"
bundle:nil];
[self presentModalViewController:aboutController animated:YES];
[aboutController release];
}
And this to come back from AboutViewController to mainViewController (code inside AboutViewController.m):
- (IBAction) backClicked:(id) sender
{
[[self parentViewController] dismissModalViewControllerAnimated:YES]
}
The reason why you get EXC_BAD_ACCESS is because after adding the view of a viewController as sub view you released the controller, hence the touch event couldn't see the intended viewController to process it.
comment out the release statement like below and it should work
- (IBAction) aboutClicked:(id)sender
{
AboutViewController* aboutController =
[[AboutViewController alloc]
initWithNibName:#"AboutViewController"
bundle:nil];
[self.view addSubview:aboutController.view];
//[aboutController release]; To avoid leaking consider creating aboutController variable at instance level and releasing it in the dealloc.
}
Try:
[self presentModalViewController:aboutController animated:YES];
To present the view and:
[self dismissModalViewControllerAnimated:YES];
To remove the view...
1) Make aboutController a class level variable
2) Create a delegate method to handle
(IBAction) backClicked:(id) sender
3) In implementation of delegate call
[aboutController.view removeFromSuperView];
I encountered some strange memory leaks executing following code on iPhone device:
#implementation TestViewController
#synthesize myButton;
- (IBAction)buttonPressed {
ABPeoplePickerNavigationController* selectContactViewController = nil;
selectContactViewController = [[ABPeoplePickerNavigationController alloc] init];
selectContactViewController.peoplePickerDelegate = self;
[self presentModalViewController:selectContactViewController animated:YES];
[selectContactViewController release];
}
Releasing the picker simple done as follows:
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[self dismissModalViewControllerAnimated:YES];
}
Instruments marks "selectContactViewController = [[ABPeoplePickerNavigationController alloc] init];" as leaking. Any idea why?
You might want to construct your Picker control like so:
ABPeoplePickerNavigationController* selectContactViewController = nil;
selectContactViewController = [[[ABPeoplePickerNavigationController alloc] init] autorelease];
selectContactViewController.peoplePickerDelegate = self;
[self presentModalViewController:selectContactViewController animated:YES];
When you present the modal view controller, it will retain the view on its own. That's how it's able to still pass you an instance of the view controller to your delegate. Best bet is to set the view controller to be autoreleased, so when it gets popped from the navigation controller, the NSAutoReleasePool will garbage collect it.
Just a comment - do you use any protocol like UINavigationControllerDelegate in the interface declaration?
I encountered a situation where just referencing this protocol caused a similar leak message.