From: cpc@panix.com (Christopher Caserio)
Newsgroups: comp.lang.objective-c
Subject: Re: instance variable declarations..
Date: 2 Sep 92 04:57:15 GMT
Organization: PANIX Public Access Unix, NYC

In <19385@ector.cs.purdue.edu> kane@cs.purdue.edu (Christopher Kane) writes:


>In article <MAS.92Aug30121306@csa.bu.edu>, mas@csa.bu.edu writes:
>> Why is it that instance variables are declared in an object's
>> @interface portion (interface file) while an object's method's are in
>> the @implementation portion (implementation file)?

>(dumb) Reason #1: Because if you don't put the instance variables in
>  the @interface, and you put them in the @implementation portion,
>  you will probably get errors from your compiler.
>  (mine says: 'inconsistent instance variable specification', and
>   claims that the instance variables used in the methods in the
>   @implementation section are 'undeclared').

Note that the interface is the definitive place for instance variables.
You cannot declare instance variables in the implementation which are
not declared in the interface. Allowing the instance variables and
other declarations in the implementation was originally intended to
facilitate automatic conversion from older versions of OC which
did not have an interface and implementation section per se.

>Reason #2: Brad Cox designed Objective-C to require the instance
>  variables in the @interface; putting them in the @implemenation
>  is just for convenience.

>  From _Object_Oriented_Programming:_An_Evolutionary_Approach_, 
>  Brad J. Cox and Andrew J. Novobilski, 2nd ed., page 89:
>  (quoted without permission)

>        I find it convenient to provide all superclass and instance
>      variable information in both files, even though Objective-C
>      only requires this information in the interface file.  If you
>      adhere to the first philosophy, you may omit the superclass
>      and instance variable information from your implementation
>      file, and will therefore need to read source code across two
>      files.  By duplicating the information about instance variables
>      and superclass information, it is available in the same file
>      with the methods.  When the information is present in both
>      files, the compiler requires that it match exactly.        

Although the quoted passage is incorrectly edited, it is usually NOT
a good idea to repeat the interface in the implementation. You will
constantly be required to maintain both copies. While this may seem
like a good idea (since you are FORCED to edit the implementation) it
is probably not necessary if you are fairly disciplined.

>> I had kind of pictured the interface file as akin to a prototypes
>> file, while the implementation file contained the actual code.  Since
>> instance variables are private data, it seems to me that they should
>> be declared in the implementation file (along with the methods) rather
>> than the interface file.

>Subclasses of a class need to have the instance variable information
>for the class as well, so the @interface section is the most convenient
>place to put them.

Absolutely the only place to put them.

>I (partially) feel the way you do, though.  There are sometimes 
>instance variables in a class which a subclass should not modify,
>either because consistancy between several variables is necessary,
>or the variable is a relatively complex data structure (eg, a linked
>list) of which you don't want to document the internals, or is
>simply private (in some way of thinking) to the class and subclasses
>should not need to "know" about it (in the way that methods not listed
>in the interface file are not "known", but are inherited as usual).
>Where necessary, the class should provide methods, which the subclass
>should use, to access these types of instance variables.

Once I again, I must agree. An early version of the OC compiler supported
the keywords: "@public", "@private", and "@readonly" between decls
in the interface. I'm not sure if this is still supported in the released
version, I'll have to check.

These keywords allowed the class designer to designate instance variables
or methods as private to the class implementation. Although the interface
is included by the subclass, the IVs marked private would not be in scope.

Providing method access to class behavior is the best way to go; since you
can override the method in subclasses, but not an instance variable.

>Indexed instance variables may be the solution here; I have never
>attempted to use that facility.  It seems to be more trouble than
>it is really worth.

Indexed instance variables are wonderful when used correctly. In most cases
though, you can get by with an encapsulated array. Using IIVs does not really
protect your data either, since a client class can acces them with "at:".

IIVs are really just additional storeage locations which are allocated after
the named instance variables, and accessed primarily with the "at:" methods.

Christopher Caserio
Newsgroups: comp.lang.objective-c