On Mar 24, 2011, at 21:49, John Engelhart wrote:
> The "problem" is that with the @interface written as MYMutableArray :
> NSMutableArray", I don't inherit the MYArray methods, which I'd very much
> like to.
You have, separately, a source code problem and couple of runtime problems.
1. At the source code level, if you have:
@interface MYArray : NSArray
@interface MYMutableArray: MYArray
then the compiler will complain if you try to assign a MYMutableArray* to a
NSMutableArray* variable. If you "fix" that with:
@interface MYArray : NSArray
@interface MYMutableArray: NSMutableArray
then the compiler will complain if you try to assign a MYMutableArray* to a
MYArray* variable. I don't see any way to solve that directly without multiple
inheritance.
You can almost get there using protocols. Here's some code I test-compiled:
> @protocol MyArrayProtocol
> @end
>
> @protocol MyMutableClassProtocol <MyArrayProtocol>
> @end
>
> typedef NSArray<MyArrayProtocol> MyArray;
> typedef NSMutableArray<MyMutableClassProtocol> MyMutableArray;
>
> ...
>
> NSArray* array = [NSArray array];
> NSMutableArray* mutableArray = [NSMutableArray array];
>
> MyArray* myArray = [MyArray array];
> MyMutableArray* myMutableArray = [MyMutableArray array];
>
> array = mutableArray;
> mutableArray = array; // incompatible pointer types
>
> myArray = myMutableArray;
> myMutableArray = myArray; // incompatible pointer types
>
> array = myArray;
> myArray = array; // oops, no warning
>
> mutableArray = myMutableArray;
> myMutableArray = mutableArray; // oops, no warning
>
> array = myMutableArray;
> myMutableArray = array; // incompatible pointer types
>
> mutableArray = myArray; // incompatible pointer types
> myArray = mutableArray; // oops, no warning
Note that class method invocations compile without error. All of the compiler
warnings are as you want them, except for the assignments labeled "oops". That
looks like a compiler bug, not a flaw in the protocol-based approach, I think.
(Without a warning, the compiler's giving you license to add compile-time
protocol conformance where it's not actually there. This is with LLVM 2.0 in
Xcode 4.) Apart from that, the above gives you exactly the compile-time
behavior you want, doesn't it?
All of that has absolutely nothing to do with what happens at run time ...
2. As far as the method swizzling is concerned, I'm not sure why you have to
use 'class_replaceMethod' on anything but '+alloc'. If you return an object of
your own class (by which I mean a private class along the lines of NSCFArray),
then you can simply implement the rest of the basic methods normally, can't
you? Also, you can use whatever runtime classes you want (including a super-
and sub-class to get the desired code sharing, or most likely just a single
class, again along the lines of NSCFArray).
The only thing this doesn't cover is what 'Class' objects your "classes"
return. I'm not sure, but I think there's enough flexibility in the runtime to
implement fictional classes, because I think sort of thing is used elsewhere
(e.g. KVO class swizzling -- which itself defines the level of fictionality
you'd have to maintain, since it works, and apps work with it).
3. As far as 'isKindOfClass' is concerned, I'd be inclined simply to override
it in your subclasses, and special-case based on the run-time-introspected type
of the parameter. There's no need I can see to painfully construct an actual
subclass hierarchy just so you can use the standard implementation. There's
also no need to reproduce the NSArray/NSMutableArray defect in your classes,
unless you decide you want to -- you *could* return the semantically proper
answer.
4. Incidentally, I can't find the answer to this in your original post, but why
do you actually need new compile-time classes for this? What if you just added
factory methods and/or alloc/inits that created objects that *claim to be*
NSArray and NSMutableArray (just like NSCFArray, basically)? Once created, let
them be different implementations of a concrete underlying class, but
NSArray/NSMutableArray for compilation purposes. IOW, join the class cluster
instead of subclassing it.
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]