What object encapsulation does Objective-C provide?
Object encapsulation can be discerned at two levels: encapsulation of instance variables and of methods. In Objective-C, the two are quite different.
However, these tricks do not help much if the method is declared elsewhere, unless one reverts to indicating the object's type at compile time. And the runtime doesn't care about all this and any programmer can easily circumvent the tricks described. Thus, all methods really are always @public.
@protocol Archiving -read: (Stream *) stream; -write: (Stream *) stream; @endOnce defined, protocols can be referenced in a class interface as follows:
// MyClass inherits from Object and conforms to the Archiving protocol. @interface MyClass: Object < Archiving > @endUnlike copying methods to/from other class interfaces, any incompatible change made to the protocol will immediately be recognized by the compiler (the next time the class is compiled). Protocols also provide better type checking without compromising the flexibility of untyped, dynamically bound objects.
MyClass *obj1 = [MyClass new]; // OK: obj1 conforms to the Archiving protocol. id < Archiving > obj2 = obj1; // Error: obj1 does not conform to the TargetAction protocol. id < TargetAction > obj3 = obj1;Another use of protocols is that you can declare an ID to conform to some protocol in order to help the compiler to resolve method name conflicts:
@interface Foo: Object -(int) type; @end @protocol Bar -(const char *) type; @end -blah1: d { id t = [d someMethod]; do_something_with ([t type]); } -blah2: d { id < Bar > t = [d someMethod]; do_something_with ([t type]); }In this example, there are two kinds of the `-type' method. In the method `-blah1:', the compiler doesn't know what return type to expect from `[t type]', since it has seen both declarations of `-type'. In method `-blah2:', it knows that `t' conforms to the `Bar' protocol and thus that `t' implements the `-type' method returning a `const char *'.
Currently, there are a number of implementations of garbage collection which can be used in Objective-C programs. Most methods use very different approaches.
In an Uncooperative Environment
This implements garbage collection of chunks of memory obtained through (its replacement of) malloc(3). It works for C, C++, Objective-C, etc.
Through Class Abstraction
This implements garbage collection through class abstraction (and hence is Objective-C specific). Anything to be garbage collectible must be an object (instance of a subclass of a specific class) or have such an object for a wrapper.
Through Reference Counting
Reference counting is a garbage collection scheme (which some do not or refuse to recognize as such) used by OpenStep and its predecessors FoundationKit and Portable Distributed Objects (PDO).
When contemplating PDO, reference counting comes naturally: every remote proxy of an object (there is proxy in each remote process referencing the object) must account for a single reference to the local object. When all remote proxies have lost interest, the local object can be removed (unless other local objects are also interested in that particules object, of course).
Cyclic Referencing
Straightforward reference counting, where an object decides to deallocate itself only upon reaching a reference count of 0, introduces the problem of cyclic referencing. This problem can be alleviated by introducing the notion of ownership. (Of couse, ownership can't be used in all situations, but at least it shows a way of thinking about the problem.)
What does ownership mean? It means that the owner can tell the object being owned that its life cycle has ended and that it should cleanup (for instance by invoking a `-cleanup' method). The object goes about releasing all its instance variables and sits around waiting for the final release which will cause its deallocation. Because the object releases all things it has retained, it is guaranteed that the object will not end up being part of an unreferenced cycle. The only thing needed for this paradigm is that the owner does a `-cleanup' before the `-release'. (There are a few other quircks, which I won't mention here.)
Put differently: ownership introduces a meta level of deallocation, where the meta level deallocation must have been performed before the non-meta level. The meta level deallocation removes the object's functionality (how much can you do when you've got nothing to remember?) and the non-meta level removes the object's storage.