Re: Garbage collector vs variable lifetime
Re: Garbage collector vs variable lifetime
- Subject: Re: Garbage collector vs variable lifetime
- From: John Engelhart <email@hidden>
- Date: Wed, 11 Jun 2008 03:01:54 -0400
On Jun 10, 2008, at 11:28 AM, Charles Srstka wrote:
I think the problem is that if NSArray has +[NSArray array]
returning an NSArray, then NSMutableArray has to return an NSArray
also, since it can't have a different method signature for the same
method. As a result, if you called +[NSMutableArray array], the
compiler would think you were getting a regular, non-mutable
NSArray, and you'd get a warning if you tried to do this, although
the code would still work:
No, each class is allowed to define different types for the same method:
http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_9_section_2.html#/
/apple_ref/doc/uid/TP30001163-CH16-TPXREF161
This whole business about '(NSArray *) means NSArray AND any of it's
subclasses' is the result of sloppy thinking and confusing 'able to'
with 'as per spec'.
If you declare a method prototype as '-(NSArray *)resultsArray', then
you have explicitly communicated that a NSArray is going to be
returned. Not a NSMutableArray. Not 'Jimmies groovy array with red
pin stripes'. A NSArray. Period. A NSMutableArray != a NSArray. If
you're going to be returning (or accepting) more than a single class,
you use id, which clearly communicates your intentions.
A return type of NSArray * means something very explicit. "But all
you can expect is an object that behaves like a NSArray, so returning
a subclass of NSArray, like NSMutableArray, is perfectly legal!"
You're exactly right that all I can expect is an object that behave
like a NSArray. /Exactly/ like a NSArray. Not sorta. Not almost.
Exactly. Because that's what you explicitly stated. So when the
returned array mutates, either because you were sloppy and returned
the pointer to your objects internal state, or because during its
travels something, somewhere sends it a mutation message inside a
@try / @catch block, I'm going to file a bug because whatever it is
you returned did not behave like a NSArray. An /immutable/ array.
Consider the following:
@interface MyObject : NSObject {
double answer;
int integerRing;
}
-(MyObject *)copyAndCombineWith:(MyObject *)object;
@end
-(MyObject *)copyAndCombineWith:(MyObject *)object
{
MyObject *copy = malloc(sizeof(MyObject));
memcpy(copy, object, sizeof(MyObject));
copy->answer += answer;
copy->integerRING += integerRing;
return(copy);
}
Then you make a subclass:
@interface ASubclass : MyObject {
NSArray *stuff;
NSView *view;
}
@end
You inevitably do something like:
@interface ASubclass
-(void)doSomething {
ASubclass *copy = [otherMyObject copyAndCombineWith:self];
}
@end
And things very obviously do not work. The reason is that doSomething
assumes that the declaration of copyAndCombineWith:(MyObject *)object
means "and any subclass". It doesn't. It means "MyObject *". I knew
that when I wrote it. I was quite explicit with the prototype. The
compiler obviously knew /exactly/ what I meant. The final clue is the
error returned for the obvious misspelling:
test.m: In function '-[MyObject copyAndCombineWith:]':
test.m:24: error: 'struct MyObject' has no member named 'integerRING'
Statically typing a class in a prototype doesn't mean "and any
subclass". It never did. The 'struct MyObject' is the tell tale
evidence that it's not even possible for MyObject * to mean "and any
subclass". When you statically type the class you mean it literally.
The fact that sending a subclass of the declared base class behaves in
a nearly indistinguishable manner is the result of careful
manipulation and subtle bending of the rules, not because it's
literally so. No amount of insisting that the illusion is real will
ever turn it in to fact.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden