Question

I have a beginner's question. I would like to have access to an UIView in all parts of my code (as opposed to a single method/function).

I therefore declared it in the @interface section

UIView *calendarView;

and then @property (nonatomic, retain) UIView *calendarView. In the @implementation I have @synthesise calendarView.

Now I would like to define the frame of this view and coded the following:

    CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
calendarView = [[UIView alloc] initWithFrame:calendarFrame];

But I am now wondering if I am doing something seriously wrong here, as calendarView has already been retained and synthesised. Surely UIView alloc is superfluous or even bound to make the app crash, as I am running into memory problems, right?

So I though I should code this instead of the two previous lines, but it only had the effect that the calendarView is not shown at all:

[calendarView setFrame:CGRectMake(170, 8, 200, 50)];

So my question is if I really need to alloc the view before I can use it? Or is there yet another solution?

Was it helpful?

Solution

you can retain an object only after you have it in memory(ie you have alloc'ed it)..So below given code is correct and needed..

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
calendarView = [[UIView alloc] initWithFrame:calendarFrame];//you have alloc'ed once

now you will add this view to a parentView. For example I am inside a UIViewController implementation..

[self.view addSubView:calendarView];  //now only your retain takes place. //So now calenderView has to release twice..Once by you (since you alloced it) and once by viewcontroller (since it has retained it)...
[calendarView release];//we are releasing once but the object will not be removed from memory since it is retained by viewController..Our part in memory management is over..Now when this viewController get dealloced it releases 

You can use this calendarView throughout the implementation of this UIViewController..

-(void)dealloc{
 [super dealloc];//should be last in dealloc..Now the entire controller will be dealloced along with the calenderView which is retained by viewController and the memory will be freed for future uses..
}

These are some useful tutorials..easier to understand than apple's documentation..But read Apple's documentation too..

http://ferasferas.wordpress.com/2010/12/05/introduction-to-memory-management-on-iphone/

http://iosdevelopertips.com/objective-c/memory-management.html

http://mauvilasoftware.com/iphone_software_development/2008/01/iphone-memory-management-a-bri.html

https://humblecoder.blogspot.com/2009/08/iphone-tutorial-memory-management.html

OTHER TIPS

Synthesizing a property doesn't actually instantiate an object for you. You'll still need your alloc and init methods.

In the code above, if you're wanting to use the property, you should be using self.calendarView rather than just calendarView. (Doing the latter is bypassing the property and using the instance variable directly, which is usually not what you want, with the possible exception of in your dealloc method.)

The one final change you should make: given that your property is marked retain, it'll handle keeping your object around itself. Therefore you should autorelease the object you're putting into it. Try this:

self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];

You actually are not doing anythin wrong in your first example other than a possible memory leak. You just have the wrong thinking that your calendarView is already retained because that was how you defined your property, which is not true. Defining your property as retain only means that when you call self.calendarView = someotherview, someotherview will be retained, the old value in calendarView will be released and calendarView will then be set to someotherview. Using calendarView without self will not provide you with any memory management rules like the property and that is why your first example is ok. You may want your code to look more like this.

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];

Yes,

You either need to alloc OR get it from others sources (release it in dealloc because you are retaining it ) before using UIView.

Use below

   CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];

Read apple documentation for memory management..

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

I therefore declared it in the @interface section

right, that just reserves space and a label to access an ivar with the type+name

and then @property (nonatomic, retain) UIView *calendarView.

right, that declares the accessors (setter+getter), and operation if synthesized

In the @implementation I have @synthesise calendarView.

that defines (implements) the accessors declared by the property declaration.

Now I would like to define the frame of this view and coded the following:

... But I am now wondering if I am doing something seriously wrong here, as calendarView has already been retained and synthesised. Surely UIView alloc is superfluous or even bound to make the app crash, as I am running into memory problems, right?

for one, your memory management is off:

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
UIView * view = [[UIView alloc] initWithFrame:calendarFrame];
self.calendarView = view; // use the setter, unless in init... or dealloc
[view release], view = 0;

two: you will not usually have much use in creating a UIView. typically, you will create a subclass of it.

three (to get to your question): there's nothing wrong with that. the variable will be nil until it's been set. the field is not default initialized for the declared type -- well, it is, but the type is in fact a pointer, so the result is that it is initialized to nil. you can either create a view or pass it in from someplace else. the view will be nil/NULL/0 until that point.

So I though I should code this instead of the two previous lines, but it only had the effect that the calendarView is not shown at all:

[calendarView setFrame:CGRectMake(170, 8, 200, 50)]; So my question is if I really need to alloc the view before I can use it? Or is there yet another solution?

stepping back to point #2 in more detail: you'll want to create a subclass in most cases. UIView/NSView does no drawing by default, but it can be used as a view container. therefore, you may want to start with some existing subclasses to get familiar with the system-supplied views.

once you have a handle on that, try implementing your own subclasses and overriding drawRect:.

many beginners like using Interface Builder (now integrated into Xc4) -- a WYSIWYG view editor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top