5

Supposedly, the interface is to talk about the Abstraction -- the Interface of a class -- what methods are available, and what arguments they take, and what the return values are -- so the instance variables being defined in the @interface section can be a bit confusing?

Those instance variables can be anything, and they are the internal implementation details -- a programmer can defined class A using 10 instance variables, and another programmer can rewrite the whole class, having the same interface (API), and use only 6 instance variables, so the instance variables are really irrelevant to the @interface section, isn't it?

Would it make more sense if the instance variables are listed in a separate section, such as a @states section, to indicate that they are the internal states of an object?

6
  • Where would you put the @states declarations? What if there were several implementation files, how would you manage the states between them if it weren't held in the public header? Commented Jun 24, 2011 at 17:44
  • Waiting for the guys who break the NDA and post here in 10..9..8.. Commented Jun 24, 2011 at 17:46
  • 1
    What about this is NDA'ed? It's a generic Objective-C question. Commented Jun 24, 2011 at 17:48
  • -1 not because it's not a valid observation, but just because it's not really a question with a decidable answer. Might be a better topic for chat than for the SO question/answer format. Commented Jun 24, 2011 at 17:57
  • The nomenclature of Objective-C can be a little confusing. What you would think of as a "class", it calls an "interface". What you would think of as an "interface", it calls a "protocol". Commented Jun 24, 2011 at 18:59

2 Answers 2

5

Originally, Objective-C classes were little more than structures within structures. I.e. say you had a subclass of NSObject and a subclass of that subclass. The compiler would effectively concatenate the ivars to create a structure that could encapsulate the ivars for the overall instance.

I.e.

{{{
  // @interface NSObject
  Class isa;
  }
 // @interface Subclass : NSObject
 int ivar1;
 int ivar2;
 }
// SubSubclass : Subclass
int ivar3;
}

Thus, the ivars had to be exposed such that the compiler could calculate the correct offsets for the various ivars in subclasses and, as you observe, what should have been an implementation detail became a part of the Class's public API.

I.e. this is the "fragile base class" problem. You can't change the ivars in a superclass without recompiling all subclasses, known and unknown, or you'll risk crashing.

This was all fixed in the "modern ABI" which came along with Objective-C 2.0, more or less (it wasn't on all platforms due to binary compatibility dependencies).

By fixing the "fragile base class" problem, it also freed the compiler to accept ivar declarations outside of the @interface, including in the @implementation, as a part of a class extension or a declaration implied by @synthesize.

End result is that your ivars can be entirely private and you can change them at whim without needing to recompile subclasses.

Sign up to request clarification or add additional context in comments.

Comments

1

You can define instance variables in the implementation file too, just try it.

Additionally, if you don't want to show the actual instance variable, but only the property-accessors, you can just define the @property in the interface and in the implementation (not the instance field), use @synthesize myProperty = _myField;. Its all there.

1 Comment

This is exactly what the new templates have started doing in the xcode. A quick note: variable names starting with _ are discouraged since they can some internal variables to the framework. To avoid this, you may use "myVariable_" instead of "_myVariable".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.