8

If I want to return an immutable array like this + (NSArray *)ids but inside this method I'm declaring a NSMutableArray because I want to sort it using -sortUsingSelector:.

Returning this method works perfect.

  • But is it "okay" to write code that declares that the return method should be one type and the actually type is another?

  • Does this work because NSMutableArray is a subclass of NSArray?

  • Is the actual return value an NSArray or an NSMutableArray?

1
  • 3
    In any language, the actual return type of a function may be a subtype of the declared return type as a consequence of the Liskov substitution principle. Commented Jul 6, 2011 at 10:28

2 Answers 2

6

(…) is it "okay" to write code that declares that the return method should be one type and the actualy type is another?

Yes, it is provided the types are compatible; see the next paragraph. In fact, there are some cases in Cocoa (notably class clusters) that do that as well.

Does this work because NSMutableArray is a subclass of NSArray?

Exactly. Since NSMutableArray is a subclass of NSArray, it inherits all its methods and declared properties, so it publicly behaves like NSArray. This is called the Liskov substitution principle.

Is the actual return value a NSArray or a NSMutableArray?

The return value is whatever you’re returning. Since you’re returning an NSMutableArray, it’s an NSMutableArray. From the caller perspective, it is an object that can be used like an NSArray.

Sign up to request clarification or add additional context in comments.

3 Comments

Returning a mutable array from a method typed as returning an NSArray * is OK, but mutating the array you get from a method typed as returning an NSArray *is not OK. If the method's declaration doesn't explicitly say it returns a mutable array, you, the caller, should never assume it returns a mutable array. Even doing this inside your own application means you are making your own code that much more fragile. If the class is telling its own array to sort itself, the method should be an accessor explicitly returning mutable. Any other class should make its own mutable copy.
@Peter Hosey: +1. The Apple docs explicitly ban treating an object as mutable if the API advertises it as immutable even if you test it first and find that it is mutable.
2
  • Whether it's "okay" or not is a difficult question. If it's a small project and only you use the code, it might be allright. However, if you rely on nothing being able to change the "NSArray" returned, it's not ok. (See the last point)

  • Yes.

  • It's an NSMutableArray. A simple cast will let you change the values in it.

If you actually want to a return an immutable object, do the following:

  NSArray* immutableArray = [[mutableArray copy] autorelease];
  return immutableArray;

1 Comment

Don't forget to autorelease it, when not running under GC or ARC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.