Re: Class Cluster Confusion
Re: Class Cluster Confusion
- Subject: Re: Class Cluster Confusion
- From: "Gerriet M. Denkmann" <email@hidden>
- Date: Sat, 21 Jun 2003 08:07:26 +0200
On Freitag, Juni 20, 2003, at 08:27 Uhr, Fritz Anderson wrote:
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.
You are right: the result of:
NSLog(@"dirContent: \"%@\"", dirContent );
dirContent: "<CFArray 0x877d0 [0xa01303fc]>{type = mutable-small, count
= 1, values = (0 : <CFString 0x1a9bf90 [0xa01303fc]>{contents =
"Reference"})}"
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.
It seems that there is a little bit more than static type checking:
id aa = [ NSArray arrayWithObject: @"kkk" ] ;
NSLog(@"Array %p aa: %@ class: %@", aa, aa, [ aa class ] ) ;
Array 0x1837b0 aa: <CFArray 0x1890f0 [0xa01303fc]>{type = immutable,
count = 1, values = ( 0 : kkk )} class: NSCFArray
id bb = [ aa mutableCopy ] ;
NSLog(@"Array %p bb: %@ class: %@", bb, bb, [ bb class ] ) ;
Array 0x17a6d0 bb: <CFArray 0x17a6d0 [0xa01303fc]>{type =
mutable-small, count = 1, values = ( 0 : kkk )} class: NSCFArray
So bb has the same class, but a different type (whatever this is good
for) of mutable-small, and has a different address, i..e. it is really
a different object, not just the same with an increased retain-count.
So the lesson seems to be: mutable methods work on NSArray, but there
is no guarantee that they will do this in future implementations.
Better make a mutableCopy and work on this.
Gerriet.
_______________________________________________
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.