Instance Variables


#1

Hi,
I m a bit confused about instance variables.
By reading some different codes, sometimes I see instance variables that are declared between the bracket like

@interface MyViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {
	IBOutlet UITableView *myTable;
	NSMutableArray *myArray;
}

and these same variables have not property directives. I mean they don’t have
@property (nonatomic,retain) IBOutlet UITableView *myTable;
But they can be used in the implementation file.

Could you tell me why and when sometimes they can be used in this way?


#2

My understanding is you only need the @property directive if you want Objective-C to synthesize the accessors (setVariable and variable) for you, using the @synthesize directive in the .m file.


#3

Yes I also understood this…
So, my sub-question is why I can use, for example, the IBOutlet myTable variable from the implementation file without creating accessors ?
Sorry for my “ignorance”… :slight_smile:


#4

IBOutlet refers to Interface Builder, (I.nterface B.uilder Outlet). All the IBOutlet is there for is as a directive to Interface Builder so the user can make the connections to an item on the screen. It has nothing to do with your source code.

A program will still compile and run without accessors created (as long as you never call them) and you can easily write around the lack of accessors:

consider:

// someClass.h
// 
#import <whatever-import-stuff-you-need>

// various other interface and class definition stuff goes here

int someIntegerUsedForSometing;

Now, without the @property declarations, xCode assumes that someIntegerUsedForSomething defaults to “atomic assign”, so unless you want them to be different than that, I think you can leave the @property statement out.

If, in someclass.m you @synthesize someIntegerUsedForSomethung, xCode creates the setSomeIntegerUsedForSomething and someIntegerUsedForSomething methods (unless you tell it to name them differently) however you don’t have to. Consider the code below, assuming I didn’t synthesize the variable in someClass.m

// appDelegate.m file

someClass myObject = [[someClass alloc] init];

/* The following line is equivalent to [myObject setSomeIntegerUsedForSomething:72];
    but given we didn't synthesize the accessors, we have to do it this way: /*

myObject.someIntegerUsedForSomething = 72;
   

(If I need to be corrected by an author because I’ve messed something up, please do so as I am still learning as well.)


#5

IBOutlet, according to the compiler, is just whitespace.

When Interface Builder reads your header file to figure out which outlets are available, it uses a relatively simple parsing mechanism: if it sees IBOutlet, the next word it sees is the type of the outlet and the word after that is the name of the outlet.

So, it doesn’t matter if you place the IBOutlet on the property declaration or the instance variable.

Also, to fix up what you were saying, scbritton, you still need to declare a property with @property. You can say

@property int something;

then the property defaults to atomic, readwrite and assign. You still definitely have to say its a property.


#6

Thanks for that, Joe.

So, then, am I correct in understanding that you only need @property if you are going to synthesize?


#7

I suppose in the real sense of the word “need”, then yes, if you plan on synthesizing, you must have a property.

But keep in mind what a property actually is: it’s a shortcut for declaring accessor methods. You only have accessor methods if you want other objects to access the ivars of an object. Synthesize is just another shortcut, allowing you to define your accessors without having to type in the code. You don’t have to synthesize a property if you want to define an accessor to be something other than the default implementation. Note, however, if you implement your own accessors, you should follow the memory management described by the property.