Why are Objective-C instance variables declared in an interface?
I'm just getting into Objective-C (Java is my primary OO language).
Defining an object's instance variables in the interface instead of the class seems strange. I'm used to an interface being a public API definition with nothing besides method signatures (not counting constants here).
Is there some reason that state is defined in an interface (even if it is private) and behaviour is defined in a class. It just seems odd that since objects are state+behavior that the definition would be split into two separate places.
Is it a design benefit is some way? A pain in the rear issue that you are just forced to deal with in Objective-C? A non-issue, just different? Any background on why it's done this way?
Or can you put object state in a class and I just haven't hit that part in my bo开发者_C百科ok yet?
UPDATE
The answer below was written before the language feature of declaring instance variables in the implementation was implemented. The premise of the question is now no longer valid. As FireLizzard says, nothing needs to go in the @interface
that you don't want to be public.
It's a hangover from the fact that Objective-C originated as a fairly thin layer built on top of C. The C way is to define the interface to a module (do not confuse with a Java interface
) in a header file and literally include it in each compilation unit. It's akin to automatically copy-pasting the declarations to the top of every compiled file. If that seems primitive, it is because it is, but C is a 40 year old language.
You have to define instance variables - even private ones - in the interface because Objective-C objects are implemented as C structs which are themselves just blocks of memory and named offsets within that block. The struct that represents an object of each class has to include space for the superclass instance variables so subclasses need to know at least the size of the C struct representing the superclass and also the public and protected instance variable offset. That, unfortunately, means that all the instance variables even private ones have to be exposed as part of the external interface.* C++ the other OO version of C suffers from the same problem for the same reasons.
It's a bit of a pain having to write down all the method signatures twice, but you get used to it.
*With the 64 bit runtime, you no longer need to declare the ivars for synthesized accessors in the @interface
but since all methods are public, it still means exposing internal state to the outside World, althoug it does alleviate the fragile base class problem.
In Objective C interface does not refer to the instance at all
Brad Cox who designed Objective C decided that the equivalent of C declarations and definitions should be made explicit so each class has a @interface section telling what it looks like externally and an @implementation saying how it is implemented.
Java came along later and changed the object model so that there is only one definition of an object which pulled the @interface and @implementation together. The compiler (and runtime introspection) in effect construct the interface from the code.
The equivalent of an interface in Java is a Protocol in Objective C.
You just get used to it.
精彩评论