Question

I have a class method in a category to construct a Cocoa collection in some way that the built-in initializers don't allow. Due to the limited initializer functionality, I have to use the mutable version of the collection to actually build it. Here's an example for NS{Mutable}IndexSet:

@implementation NSIndexSet (WSSNonContiguous)

+ (instancetype)WSSIndexSetFromMask:(NSUInteger)mask
{
    NSMutableIndexSet * set = [NSMutableIndexSet indexSet];

    for( NSUInteger i = 0; i < (sizeof(NSUInteger) * 8); i++ ){
        if( mask & (1l << i) ){
            [set addIndex:i];
        }
    }

    return set;
}

My return type is sometimes a lie here -- there's always a mutable collection being returned, whether the user is requesting an immutable version or not.

Is it still appropriate to use instancetype in cases like this, or should I go with id? If I do use instancetype, should I also be explicitly re-creating the collection:

// Ick?
return [[self alloc] initWithIndexSet:set];

to make sure an immutable copy is returned when the call is +[NSIndexSet WSSIndexSetFromMask:]?

Was it helpful?

Solution

Everything is okay:

NSIndexSet *set = [[NSIndexSet WSSIndexSetFromMask:0] addIndex:0];

No visible @interface for 'NSIndexSet' declares the selector 'addIndex:'

instancetype says to the sender, that you return a instance of the receivers type even it is a subtype. For the sender it is a NSIndexSet, because it is send to the class object of NSIndexSet.

An introspection that way, that someone looks to the return type and sees a subclass and takes any advantage out of this information, is malformed. The contract is build with the return type and this is in this case NSIndexSet.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top