Hi,
You don’t actually need anything new from the runtime to support this. I implemented something equivalent in the EtoileFoundation framework around 2007 and GNUstep also has something similar in -Base Additions.
Categories are somewhat problematic in Objective-C because there is no defined composition order. A lot of other languages have solved this in various ways. In Verona, we’re addressing it by allowing default methods on interfaces not allowing subclassing and getting most the benefits (and almost none of the overhead) that Smalltalk and Objective-C derive from this dynamic behaviour from a structural and algebraic type system.
Categories, in the runtime, are just a little bit of metadata with a list of methods and a class to apply them to. You could make this entirely declarative by defining a protocol like GSConcreteProtocol (containing no methods) and then define a class that implements that protocol and another protocol with optional methods, so you’d write something like this:
@protocol Example
@required
- (void)mustBeImplemented;
@optional
- (void)hasDefaultImplementation;
@end
@interface ExampleConcreteProtocol : NSObject<Example, GSConcreteProtocol> @end
@implementation ExampleConcreteProtocol
- (void)mustBeImplemented { /* Keep the compiler happy */ }
- (void)hasDefaultImplementation
{
// Some code goes here
}
@end
You’d then use the runtime’s introspection to get the list of all classes and first find all classes that conform to the GSConcreteProtocol protocol. Then you’d probably do some sanity checking (e.g. that they inherit directly from NSObject and have no other ivars) and then, for each of these classes, you’d find the protocols that they conformed to.
Next, you’d find all other classes that conformed to that protocol. You’d then iterate over all of the optional methods in the protocol and find ones that are not implemented by the class, then copy the method from the concrete protocol class into the target.
The end result is that you provide a class that implements the optional methods in a protocol and then any class that adopts the protocol but does not define the methods gets the default implementation.
This requires that the runtime support protocol introspection to find optional methods. This should all be working with both v1 and v2 GNUstep ABIs.
David