• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Class Cluster Confusion
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Class Cluster Confusion


  • Subject: Re: Class Cluster Confusion
  • From: Fritz Anderson <email@hidden>
  • Date: Fri, 20 Jun 2003 13:27:42 -0500

On Thursday, June 19, 2003, at 06:56 AM, Gerriet M. Denkmann wrote:

NSFileManager *defaultManager = [ NSFileManager defaultManager ];
id dirContent = [ defaultManager directoryContentsAtPath: aPath ];
NSLog(@"dirContent class: \"%@\"", [ dirContent class ] );

// class is NSCFArray, which is also what the documentation tells me.

// this is a method of NSMutableArray, not of NSArray:
[ dirContent removeObjectAtIndex: 0 ] ;

Now I would expect a run-time error: "-[NSCFArray removeObjectAtIndex:]: selector not recognized", but it just works.
Why?

Because the NSFileManager generated the directory listing internally by allocating an NSMutableArray and adding elements to it. When it was done, it did not take the extra time to allocate an immutable copy, but gave you its working copy.

The specification (NSArray *) on the return value never indicated the literal class of the return value anyway (NSArray has no implementation); it indicated the set of messages the return value responds to. Apple engineers have said before, on this list, that they use immutable types in the API as indications of the nature of return values (you aren't getting a dynamic or mapped listing), and of the safety of changing them (you may be getting a pointer to an internal buffer, which is mutable for the owner's purposes, but if you change it, you may corrupt a data structure).

// Then I did:
NSMutableArray *mutants = [ [ NSMutableArray alloc ] initWithCapacity: count ] ;
NSLog(@"mutants class: \"%@\"", [ mutants class ] );
// class is again NSCFArray

Does this mean that there is no such thing as a NSMutableArray? That this is always the same as NSArray? That the distinction is only for static type checking?

Or what am I misunderstanding here?

It may be that there's only one underlying implementation of NSArray -- I see that
[NSArray arrayWithObjects: @"fee", @"fie", @"foe", @"fum", nil];
also is of class NSCFArray. So yes, for the moment it's for static type checking, and for documentation. However, you are always free to write:

@interface NSArray (immutability)
- (void) addObject: (id) obj;
- (void) insertObject: (id) obj atIndex: (unsigned) index;
- (void) removeLastObject;
- (void) removeObjectAtIndex: (unsigned) index;
- (void) replaceObjectAtIndex: (unsigned) index withObject: (id) obj;
@end

@implementation NSArray (immutability)

- (void) addObject: (id) obj
{
[self doesNotRecognizeSelector: _cmd];
}

/* And similarly for the others */

@end

And then you have runtime type checking -- the "selector not recognized" error you were looking for.

-- F

--
Fritz Anderson - Consulting Programmer - Chicago, IL
Mail: <email@hidden>
Risumi: <http://resume.manoverboard.org>
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: Class Cluster Confusion
      • From: "Gerriet M. Denkmann" <email@hidden>
References: 
 >Class Cluster Confusion (From: "Gerriet M. Denkmann" <email@hidden>)

  • Prev by Date: Re: Not a drawer but a ... ?
  • Next by Date: Re: trivial question
  • Previous by thread: Class Cluster Confusion
  • Next by thread: Re: Class Cluster Confusion
  • Index(es):
    • Date
    • Thread