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
Related
I developed an iPhone project without XIB files. In that I manually created the UIView object and a few more components on that view also. I release these objects in my dealloc and viewDidUnload methods. My problem is that if I release the UIView object the app crashes and I do not know why. Can anyone help me in this issue?
Here is my code:
allmessengersview = [[UIView alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
allmessengersview.backgroundColor = [UIColor whiteColor];
self.view = allmessengersview;
-(void) dealloc {
[allmessengersview release];
[super dealloc];
}
- (void) viewDidUnload {
[super viewDidUnload];
[allmessengersview release];
allmessengersview = nil;
}
Please Write Down this Code in Initialization in View
allmessengersview=[[UIView alloc]init];
allmessengersview.frame = CGRect (0,0,320,480);
allmessengersview.backgroundColor = [UIColor whiteColor];
[self.view addsubView: allmessengersview];
Please Write Down this Code in Dealloc Methods
-(void)dealloc
{
[allmessengersview release];
[super dealloc];
}
Don't release in viewDidUnload.
This way the app will release allmessengersview in the viewDidUnload and later on it tries to release it a second time in dealloc, but since it's already released, the app crashes.
This is my first post and you are my last hope.
I have a list with images in my iPad app, if you select one, my class MyViewController which extends UIViewController is loaded and shown (by just setting window.rootViewController, by using UINavigationController, by presentModalViewController - tried everything, doesn't make any difference). It has a UIScrollView inside, which adds a big version of the image to the UIScrollView with this code:
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[[delegate getImageNames] objectAtIndex:(gameNr*2)]]];
tempImageView.frame = CGRectMake(0,0,tempImageView.frame.size.width/2,tempImageView.frame.size.height/2);
[self setMyImage:tempImageView];
[tempImageView release];
myScrollView.contentSize = CGSizeMake(myImage.frame.size.width, myImage.frame.size.height);
myScrollView.maximumZoomScale = 2.0;
myScrollView.minimumZoomScale = 1.0;
myScrollView.clipsToBounds = YES;
myScrollView.bounces = NO;
myScrollView.delegate = self;
[myScrollView addSubview: myImage];
myImage is a (nonatomic, retain) property of the type UIImageView inside my MyViewController.
After pressing a button and go back to the list of images, I release the reference to MyViewController and it's dealloc method is called like this:
- (void)dealloc
{
CFShow(#"dealloc!");
for(UIImageView *subview in [myScrollView subviews]) {
if(subview.frame.size.width > 20){
[subview removeFromSuperview];
[subview setImage:nil];
}
}
[myImage setImage:nil];
self.myScrollView = nil;
self.myImage = nil;
[myScrollView release];
[myImage release];
[super dealloc];
}
It works so far, but the problem is, that the memory of the images is not really deallocated this way. After opening and closing about 12 images, the app crashes with memory warning.
This is also confirmed by the report_memory method I got from here:
iOS Low Memory Crash, but very low memory usage
The dealloc method IS called, that's triple checked.
I checked the variables myImage and myScrollViewvia breakpoint in the debugger, they are set to 0x0 by those commands in the dealloc method. Why is the memory not freed????????
Thanks for any suggestion, I am working on this since three whole days, it's driving me crazy.
Replace this:
self.myScrollView = nil;
self.myImage = nil;
[myScrollView release];
[myImage release];
with this:
[myScrollView release];
self.myScrollView = nil;
self.myImage = nil;
And post code where you define property myScrollView and init it.
And you don't need loop for(UIImageView *subview in [myScrollView subviews]). When you will release myScrollView object it will automatically release all its subviews.
I wonder if someone could quickly help me with the following, do I need to add a [myTableView release]; after I call [view addSubview:[self myTableView]]; ? Initially I was thinking no, and running it through CLANG produced to memory warnings
Here is my thinking:
[self setMyTableView:tempTableView]; retainCount = (+1)
[view addSubview:[self myTableView]]; retainCount = (+2)
//[myTableView release]; << HERE retainCount = (+1)
-dealloc [myTableView release]; retainCount = ( 0)
.
#property (nonatomic, retain) UITableView *myTableView;
.
- (void)loadView {
NSLog(#"%s", __PRETTY_FUNCTION__);
[self setTitle:#"Location Data"];
CGRect viewFrame = CGRectMake(0, 20, 320, 460);
UIView *view = [[UIView alloc] initWithFrame:viewFrame];
CGRect tableFrame = CGRectMake(0, 0, 320, 416);
UITableView *tempTableView = [[UITableView alloc] initWithFrame:tableFrame];
[self setMyTableView:tempTableView];
[tempTableView release];
[view addSubview:[self myTableView]];
//[myTableView release]; << HERE
[[self myTableView] setDelegate:self];
[[self myTableView] setDataSource:self];
[self setView:view];
[view release];
}
.
- (void)dealloc {
[myTableView release];
[dataModel release];
[super dealloc];
}
EDIT: hmm maybe I don't as [view addSubview:[self myTableView]]; retains it and will release when done. Your right Carl, my bad. I was getting confused with: alloc, set, release, when this is simply the view taking ownership (and the responsibility to release that later)
You're right when you say that [view addSubview:[self myTableView]]; will retain your table view, but since it's the view who is retaining it, it's the view that is supposed to release it. And it will, when the view gets dealloc'ed. You only have to release what you retained yourself, i.e., you only have to release the table view once in your dealloc method.
Your method doesn't retain myTableView, so it shouldn't release it.
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.
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;
}