when I try to release a dictionary I get an exception.
Here is my code:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!tableDataDictionary)
{
DebugLog(#"initializing tableDataDictionary");
tableDataDictionary = [ [NSMutableDictionary alloc] init];
}
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[mainTableView deselectRowAtIndexPath: [mainTableView indexPathForSelectedRow] animated:NO];
[tableDataDictionary release];
}
How can I fix it?
Most likely you need to nil out the tableDataDictionary instance variable. Otherwise, the first time each of these methods run, it will work fine, but the second time, tableDataDictionary will not be nil, and will be pointing at a dealloc'd pointer; thus the alloc call will not be made, and when viewWillDisappear: is called, it will try to dealloc that pointer again. So, to fix it:
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[mainTableView deselectRowAtIndexPath: [mainTableView indexPathForSelectedRow] animated:NO];
[tableDataDictionary release];
tableDataDictionary = nil;
}
Related
I have a split view controller in my app's contact page.. and i am unable to hide the navigation bar in my page.. Can anyone help me on hiding the navigationBar. i have attached my code
- (void)viewDidLoad
{
self.navigationController.navigationBarHidden = YES;
splitViewController.navigationController.navigationBarHidden = YES;
appdelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
[super viewDidLoad];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
[[VHeaderView sharedVHeaderView] viewWithCommonHeaderOnView1:self.view];
}
else
{
[[VHeaderView_iPad sharedVHeaderView_iPad] viewWithCommonHeaderOnView1:self.view];
}
[splitViewController.view setFrame:CGRectMake(0,48, 768, 1024)];
// [self.view removeFromSuperview];
//self.view.frame=CGRectMake(0,100, 768, 1024);
[self.view addSubview:splitViewController.view];
}
Try this. works for me. Make sure that navigation controller is allocated.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO];
}
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
[super viewWillDisappear:animated];
}
put this code in your .m file
if u don't wish to animated effect then set no.
Callled only once this method.
try to put your code in ViewWillAppear
-(void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
try this code
I am new to iPhone Development.
I have taken UIView,UIImageView,UIScrollView etc in my NIB File.
My question is that can i remove all that views from SuperView ?
For Example:`
-(void)dealloc
{
[super dealloc];
[imageView removeFromSuperview];
[View1 removeFromSuperview];
[View2 removeFromSuperview];
[ScrollView removeFromSuperview];
[imageView release];
[View1 release];
[View2 release];
[ScrollView release];
imageView = nil;
View1 = nil;
View2 = nil;
ScrollView = nil;
}
please help me.Thanking you...
You need to call [super dealloc]; as the very last thing, not first. That's because [super dealloc] cleans up your object, and accessing instance variables afterwards is undefined behavior: anything can happen. For example, [super dealloc] could set all instance variables to nil, in which case the following release calls simply have no effect (and thus cause leaks). Also, there's no need to set the instance variables to nil since you're not going to use them anyway. So all you need is:
-(void)dealloc
{
[imageView release];
[View1 release];
[View2 release];
[ScrollView release];
[super dealloc];
}
A few more notes: the removeFromSuperview calls are harmless but unnecessary, this is implicitly done by [super dealloc]. And you should stick to Apples naming conventions which in your case means you shouldn't start variable names with uppercase letters. So it should be scrollView instead of ScrollView.
No need to remove those subviews from superview, since anyhow you are going to release the superview itself.
You can make the dealloc as follows.
-(void)dealloc{
[imageView release];
[View1 release];
[View2 release];
[ScrollView release];
imageView = nil;
View1 = nil;
View2 = nil;
ScrollView = nil;
[super dealloc];
}
Note that [super dealloc] is at the end (More info).
You might want to enable ARC in your projects. You won't need to release these objects anymore; the system will take care of (most of) your memory-management.
You can read more about ARC here: http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html
I have a view controller that is an NSStreamDelegate, I have a problem when the view is popped from the navigation controller while something is being streamed I get a "EXC_BAD_ACCESS" error. I have tried closing the stream, but it doesn't seem to stop it if there is a stream in progress. What is the proper way to handle this, can you delay the view from popping if something is being streamed?
#import "CameraViewer.h"
#implementation CameraViewer
#synthesize camService;
#synthesize currentDownload;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil theService:(NSNetService *)cameraService {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
[self setCamService:cameraService];
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
[self downloadAgain];
}
- (void)viewWillDisappear:(BOOL)animated{
NSLog(#"view is going away");
NSInputStream *istream;
[camService getInputStream:&istream outputStream:nil];
[istream close];
NSLog(#"view is gone");
[super viewWillDisappear:animated];
}
- (void)downloadAgain{
NSInputStream *istream;
[camService getInputStream:&istream outputStream:nil];
[istream retain];
[istream setDelegate:self];
[istream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[istream open];
}
#pragma mark NSStream delegate method
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)event {
switch(event) {
case NSStreamEventHasBytesAvailable:
NSLog(#"Reading Stream");
if (![self currentDownload]) {
[self setCurrentDownload:[[NSMutableData alloc] initWithCapacity:409600]];
}
uint8_t readBuffer[4096];
int amountRead = 0;
NSInputStream * is = (NSInputStream *)aStream;
amountRead = [is read:readBuffer maxLength:4096];
[[self currentDownload] appendBytes:readBuffer length:amountRead];
//NSLog(#"case 1");
break;
case NSStreamEventEndEncountered:
[(NSInputStream *)aStream close];
UIImage *newImage = [[UIImage alloc] initWithData:[self currentDownload]];
[self setCurrentDownload:nil];
if(newImage != nil){
[imageView setImage:newImage];
}
[newImage release];
[self performSelector:#selector(downloadAgain) withObject:nil afterDelay:0.25];
break;
default:
break;
}
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[[self camService] release];
[[self currentDownload] release];
[super dealloc];
}
#end
I see that you call scheduleInRunLoop. In that case, when you don't need the stream, you should also call
[istream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode: NSDefaultRunLoopMode];
after you've closed the stream.
What is happening is whatever instance of the CameraViewer class (which is set to be the delegate) is being deallocated (causing EXC_BAD_ACCESS in the run loop) because you didn't retain it.
The solution is to either call retain on the CameraViewer class at instantiation, like so:
CameraViewer *cameraViewer = [[CameraViewer alloc] init];
[cameraViewer retain];
Im have a slight amount of trouble adding a new view to my scene, I have the code like this:
- (void) showMyDayView {
NSLog(#"My Day View was touched");
MyDayViewController *temp = [[MyDayViewController alloc] initWithNibName: #"MyDayView" bundle:nil];
self.myDayViewController = temp;
NSLog(#"superview: %#", [[self mainNavView] superview]);
[[self mainNavView] removeFromSuperview];
NSLog(#"after removal main: %#", [self mainNavView]);
NSLog(#"after removal view: %#", [self view]);
NSLog(#"after removal superview: %#", [[self view] superview]);
[[[self view] superview] addSubview: [self.myDayViewController view]];
[temp release];
}
And when I run this code, the console says "after removal superview: (null)"
so when I add the subView to the superview, nothing happens because the superview is null.
Any ideas?
Thanks
Mark
If you want to reuse a view that you are going to removeFromSuperview, you must retain it first. removeFromSuperview releases any view it is invoked on.
So...
[[self mainNavView] retain]
[[self mainNavView] removeFromSuperview];
And [self mainNavView] remains safe to use.
I have a big problem since a few days that I can't solve.
First I have a login view controller with this code :
#implementation MMConnectionViewController
#synthesize login, password, activityIndicator, mainVC;
- (BOOL)textFieldShouldReturn:(UITextField *)aTextField
{
[aTextField resignFirstResponder];
[self performSelectorOnMainThread:#selector(startRolling) withObject:nil waitUntilDone:NO];
[NSThread detachNewThreadSelector:#selector(connect) toTarget:self withObject:nil];
return YES;
}
- (void)viewWillAppear:(BOOL)flag {
[super viewWillAppear:flag];
[login becomeFirstResponder];
login.keyboardAppearance = UIKeyboardAppearanceAlert;
password.keyboardAppearance = UIKeyboardAppearanceAlert;
[self setTitle:#"Monaco Marine"];
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Logout"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];
[backBarButtonItem release];
}
- (void)connect {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
mainVC = [[MMMainViewController alloc] initWithLogin:login.text password:password.text connectPass:#"1" navigationController:self.navigationController nibName:#"MMMainViewController" bundle:nil];
if (mainVC) {
[self performSelectorOnMainThread:#selector(dataLoadingFinished) withObject:nil waitUntilDone:YES];
}
[pool release];
}
- (void)dataLoadingFinished {
self.stopRolling;
[self.navigationController pushViewController:mainVC animated:YES];
}
- (void)showAlertWithMessage:(NSString *)message {
self.stopRolling;
NSLog(#"%#",message);
UIAlertView *warning = [[UIAlertView alloc] initWithTitle:#"Connection Failed" message:[NSString stringWithFormat:#"%#",message] delegate:self cancelButtonTitle:#"Retry" otherButtonTitles:nil];
[warning show];
[warning release];
}
- (void)startRolling {
[activityIndicator startAnimating];
}
- (void)stopRolling {
[activityIndicator stopAnimating];
}
- (void)viewDidLoad {
[login becomeFirstResponder];
}
- (void)dealloc {
[login release],login=nil;
[password release],password=nil;
[activityIndicator release],activityIndicator=nil;
[super dealloc];
}
After, there's MMMainViewController with this code :
#implementation MMMainViewController
#synthesize login, password, connectPass, navigationController, accountVC;
- (void)viewDidLoad {
// Set a title for each view controller. These will also be names of each tab
accountVC.title = #"Account";
accountVC.tabBarItem.image = [UIImage imageNamed:#"icon_user.png"];
self.view.frame = CGRectMake(0, 0, 320, 480);
// Set each tab to show an appropriate view controller
[self setViewControllers:
[NSArray arrayWithObjects:accountVC, nil]];
[navigationController setNavigationBarHidden:NO animated:NO];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Menu"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[self setTitle:#"Menu"];
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithLogin:(NSString *)l password:(NSString *)p connectPass:(NSString *)c navigationController:(UINavigationController *)navController nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
contentView.backgroundColor = [UIColor whiteColor];
self.view = contentView;
[contentView release];
login = l;
password = p;
connectPass = c;
navigationController = navController;
if (!accountVC)
accountVC = [MMAccountViewController alloc];
[self.accountVC
initWithNibName:#"MMAccountViewController" bundle:nil];
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
return self;
}
- (void)dealloc {
[connectPass release];
[login release];
[password release];
[super dealloc];
}
The layer MMAccountViewController loaded from MMMainViewController is a basic view controller with nothing in it.
Now the problem is that sometimes when load my tabbed view controller and I go back to the login view controller, the screen freezes and bug with message (NSZombieEnabled = YES) :
*** -[CALayer retain]: message sent to deallocated instance 0xd0199d0
This is all I have and I really can't see where I'm wrong.
Some more idea?
Thanks for those who help me!
You are overreleasing something somewhere. You might want to run your application in Instruments to check where it may be happening (XCode: Run->Run With Performance Tool->Leaks will give you the setup that you need afaik). I can't see anything in your code, but you said yourself that you use "roughly" this code, so it may not be in this part of your program.
Update:
I still can't see that you overrelease something somewhere... I'm pretty sure the problem is not within this part of the code. If you haven't found the problem yet, you may want to try and create a test case, that is, a small program that tries to mimic this programs behavior and reproduce the bug. If you can reproduce it within a small program, I'll take a look at that.
I was also encounter the same problem, and the problem was that I was assigning a UIButton to the rightNavigationItem and release that button instance, I just remove the release code and started working.