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 (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to