开发者

In Objective-C, the @interface section lists the instance variables... isn't it somewhat misplaced?

开发者 https://www.devze.com 2023-03-15 17:59 出处:网络
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 va

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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号