I have a project where I want to open a UITableViewController after a UITableViewController via a UINavigationController. The thing is, it works the first time when it gets called by this function:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SDMetadataEntity *entity = [self.optionItems objectAtIndex:indexPath.row];
SudzcDetailViewController *detailViewController = [[SudzcDetailViewController alloc] init];
detailViewController.refName = entity.Name;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
[entity release];
}
But when I press the back button on the navigation bar, and press the same item again, it crashes! It doesn't crash when I press a different item in the first UITableViewController. I would really like to learn from what I am doing wrong!
You should not
[entity release];
because when you do
[self.optionItems objectAtIndex:indexPath.row];
you just fetching a pointer to it, not init/copy/retaining it.
You shouldn't be releasing entity.
You got that object from an array, you don't own it, so when you release it you may be causing it to be deallocated prematurely.
Related
I want to build an app for playing local audio files on the iPhone but I'm stuck with some of my codes.
I'm wondering how you can push a view, come back to the uitableviewcontroller and use a button ( like the "NOW PLAYING" button in the media player) to come back to the view without pushing any new string into it..
THANK YOU
What should I change from my codes ?
in the uitableviewcontroller..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath {
selectedSong = [directoryContent objectAtIndex:indexPath.row];
NSString *storyLin = [[directoryContent objectAtIndex:[indexPath row]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
patch = [NSString stringWithFormat:#"/%#", storyLin];
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
myDetViewCont.myProgLang = selectedSong; // assigning the correct value to the variable inside DetailViewController
[self.navigationController pushViewController:myDetViewCont animated:YES];
[myDetViewCont release]; // releasing controller from the memory
}
in mPlayerViewController.m
-(IBAction) backtoplayer{
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
}
If you have pushed a view onto the navigation controller, just pop it to review the view underneath.
That is, the view you push myDetViewCont should just be popped in the backtoplayer call.
- (IBAction)backToPlayer:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
To Add to what Mark said.
Once you've popViewControllerAnimated and the user want to push the same controller again, you just need to keep the mPlayerViewController rather than release it.
Such as:
if (!myDetViewCont)
{ // We only need to create it once.
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
}
myDetViewCont.myProgLang = selectedSong;
[self.navigationController pushViewController:myDetViewCont animated:YES];
// no longer release here, move the release call to the dealloc
I have the following code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
if (tvc == nil)
tvc = [[TopicViewController alloc] initWithNibName:#"TopicViewController" bundle:nil];
tvc.title = #"Topic";
tvc.topicId = [[results objectAtIndex:indexPath.row] objectForKey:#"id"];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:tvc animated:YES];
[tvc release];
}
So when I tap on the row it is able to bring this table view. Then I press navigate back and choose a different row, then the app crashes. I tried to see in the console for any error, but can't find any. What is wrong?
I believe your (tvc == nil) is returning NO because you released tvc but didn't set it to nil so next time this method is accessed, you try and push it as a view controller without allocating it again, hence the crash.
You can either remove the if (tvc == nil) check or release tvc and then set it to nil with [tvc release], tvc = nil;.
The other possibility is your results array is being released. Where is it initialised and have you declared a retain property for it? If so you can access it with [self.results objectAtIndex:...] which will guarantee it will stick around until your view controller is deallocated.
#Equinox i think you need to do something like this
tvc.title = [[NSString alloc] initWithFormat:#"Topic"];
tvc.topicId = [[NSString alloc] initWithString:[[results objectAtIndex:indexPath.row] objectForKey:#"id"]];
Edit: i think you are over releasing some objects in your TopicViewController class so your app is getting crash with out any message in the console. what you can do is build and analyze your project to check for any over releasing objects
You're always releasing, even if it's not allocated.
Assuming tvc is a declared property that retains an object, do
self.tvc = [[TopicViewController alloc] initWithNibName:#"TopicViewController" bundle:nil];
//....
self.tvc = nil;
[tvc release];
instead of
tvc = [[TopicViewController alloc] initWithNibName:#"TopicViewController" bundle:nil];
//....
[tvc release];
However, I wouldn't release the view controller and re-allocate it at all, because a memory allocation is expensive. I would just store one tvc object and reuse it, by modifying it according to the selected row.
I created iOS application from Navigation-based application template.
This snippet is from RootViewController.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DotoViewController *detailViewController = [[DotoViewController alloc]
initWithNibName:#"DotoViewController" bundle:nil];
NSManagedObject *selectedObject = [[self fetchedResultsController]
objectAtIndexPath:indexPath];
detailViewController.dotoObj = selectedObject;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
DotoViewController is a subclass of UIViewController and has an accompanying NIB file.
Upong clicking on a row, DotoViewController is getting displayed but without the back button to RootViewController on the left side.
What I'm missing?
Perhaps your root view controller has an empty title? The view controller's title is used as the title for the back button, so if you have an empty string there, this can cause the back button to disappear. If it's nil, it should display the standard "Back" though.
I am having problems with getting a detail view to load using pushViewController. At first, I thought pushViewController was not working. BUT, then I tried using a different view controller and it worked. I can tell from tracing that the problem view controller is never loaded at all. In other words, I tried to eliminate the possibility that there was some error in the view controller by NSLoging in that object and I never see anything.
Does anyone have any ideas?
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
NSLog(#"hsitkjsdfkljlkd");
if (childController == nil)
childController = [[salesViewController alloc] initWithNibName:#"salesView" bundle:nil];
//NSUInteger row = [indexPath row];
[self.navigationController pushViewController:childController
animated:YES];
*/
/*
//modal = blocking
salesViewController *otherVC = [[salesViewController alloc] initWithNibName:#"salesView" bundle:nil];
//must set sale type
otherVC.strSaleType = #"Voice";
[self presentModalViewController: otherVC animated:YES];
//No close. By design, it is up to the otherVC to close itself
*/
//tipCalcViewController *detailViewController = [[tipCalcViewController alloc] initWithNibName:#"tipCalcView" bundle:nil];
salesViewController *detailViewController = [[salesViewController alloc] initWithNibName:#"salesView" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
Just Check the
- (void)viewWillAppear:(BOOL)animated
{
}
of the salesViewController.
you are doing something wrong in this..
put the debugging point in the viewWillAppear and run it. you can get the error line..
just try it......Surely it will work for u...
salesViewController *detailViewController = [[salesViewController alloc] initWithNibName:#"salesViewController" bundle:nil];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
Also make sure you are giving the IBOutlet connection to UIView.
In my case I had several IBOutlets that I removed from the Header file and forgot to remove the connection to these non-existing outlets in Interface Builder. So removing the obsolete outlets fixed the problem in my case.
When you're pushing from ViewController1 to ViewController2 then the code will be used like this so try this code,
ViewController2 *vw2=[[ViewController2 alloc]initWithNibName:#"ViewController2" bundle:nil];
[self.navigationController pushViewController:vw2 animated:YES];
The Above code may be written on Click event of button or on didSelect delegate of UITableView
Right now I have an indexed UITableView that goes to a detail view but i want it to go to another UITableView then a detail view.
my code like this:
`
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
displyAnnController *anController = [[displyAnnController alloc] initWithNibName:#"AnnView" bundle:[NSBundle mainBundle]];
DetailViewController *dvController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
switch (indexPath.row) {
case 0:
[self.navigationController pushViewController:anController animated:YES];
[anController release];
anController = nil;
break;
case 1:
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
break;
default:
break;
}`
and when I press the cell with index 0 in the simulator, the program is crash!
what's the problem? pleas help me ..
No, I didn't override the -initWithNibName, I just use it as the same way here,but to push to ControlView NOT TableView.Also,no errors in debug console.
and I have tried to release the controllers after the switch block, but the program still crash :(
anyway, it's work when I write:
displyAnnController *anController = [[displyAnnController alloc] initWithStyle:UITableViewStyleGrouped]];
instead of :
displyAnnController *anController = [[displyAnnController alloc] initWithNibName:#"AnnView" bundle:[NSBundle mainBundle]]
Temporarily, I accept this just to complete my work! but I hope to find any help example because no need to be as group.
thanks all for help and recommendations.
View the debug console (Cmd-Shift-R) and see what the error is.
Are you overriding the -initWithNibName message on displyAnnController? Or the -viewDidLoad message?
You also have a memory leak. You always +alloc both controllers, but only -release one of them. Don't +alloc your controller unless you are going to actually use it.
I think your application is crashing because first you have released the view and then you are making it nil.If it is released once then it is not getting the reference to make it nil.Try it once.It may work.