Re: Q's about Obj-C
Re: Q's about Obj-C
- Subject: Re: Q's about Obj-C
- From: Ondra Cada <email@hidden>
- Date: Mon, 15 Oct 2001 18:11:08 +0100
Joe,
>
>>>>> Joe Chan (JC) wrote at Mon, 15 Oct 2001 11:23:20 -0400:
JC> 1. When I'm defining the init method for my derived class, I
JC> read that I need to deal with [super init] returns nil. It's not
JC> entirely clear to me when that happens, who should dealloc the
JC> memory of the object? It doesn't seem right to me for the
JC> derived classes to deal with it, because if every derived class
JC> does it, there will be two many dealloc's chained together. The
JC> only place it seems sensible to dealloc is from the actual init
JC> method of the class that decides to return nil for some reason.
JC> Is that indeed the case?
Quite right. The proper "derived" code is something like
-init {
if ((self=[super init])==nil) return nil;
... normal initialization ...
return self;
}
JC> 2. It's not clear to me when I need to declare a method in the
JC> header file.
Actually, you don't ever declare methods. You declare messages, rather: the
methods occur in implementation only, and are called by runtime as a result
of sending some message (generally, but not necessarily, declared in some
header) to an object.
JC> From my reading of the Vermont Recipes at Stepwise,
JC> the language does not require me to declare methods in the
JC> header file if I override the super's method, or implement a
JC> delegate method. Does that mean the only time I need to declare
JC> a method in the header is when I introduce a new method to the
JC> class?
Actually, the language _NEVER_ requires message declaration.
If you know plain C well, consider function headers. In ObjC, it's _EXACTLY_
the same: the only difference is that an "unknown" function would return an
int, whilst an unknown message would return an id (those are convertible
anyway).
Apart of that, you would want to declare
(a) all new _PUBLIC_ messages, so that the compiler knows them and would not warn;
(b) those "old" (ie. known to compiler from any other header) messages which
are implemented in some non-quite-obvious way, so as you can comment on that
in headers;
(c) those "old" messages which you seldom overwrite, in cases when another
user of your class would need to know that.
As for (a), if you have some methods which are used only internally, don't
ever declare the appropriate messages in header. If needed (to suppress
warnings), do that in a category in implementation.
As for (c), a good example might be awakeFromNib, so as anybody who might
want to subclass your class knows that if he uses it, a [super awakeFromNib]
would be in order.
JC> 3. About the fact that all method of the same name needs to
JC> receive the same argument and return types. I'm a little
JC> confused by that. Does that apply only to the case of overriding
JC> existing method? Say if I have two classes A and B that belongs
JC> to different class hierarchies, and they both declare method foo:
JC>
JC> @interface A : ParentOfA
JC> -(int)foo: (float)arg;
JC> @end
JC>
JC> @interface B : ParentOfB
JC> -(void)foo: (int)arg;
JC> @end
JC>
JC> Is this illegal? If so, how does one go about ensuring unique
JC> method names within a potentially large class hierarchy?
It's quite legal. ObjC, unlike those toy languages like C++ or Java,
supports true polymorphism -- you can send the message "foo:" to any object;
if it happens to have an appropriate method (or use forwarding), it will be
called.
Originally, this idea was invented in SmallTalk where there was just the
type id, so no problems were possible. With ObjC complete C-inherited type
zoo, you might have to cast explicitly to say compiler which types should be
used:
id o;
[o foo:1]; // issues a warning, and compiles randomly (A) or (B)
[(A*)o foo:1]; // converts 1 to double (A)
[(B*)o foo:1]; // uses 1 as an integer (B)
JC> 4. What makes a class an abstract class? In C++, that's caused
JC> by a pure virtual function, but there doesn't seem to an
JC> equivalent in Obj-C.
What is it "an abstract class"? ;))))
In dynamic system, you can't prevent instantialization compile-time like in
C++. What's better, you don't want to: since the alloc/init messages are so
much more flexible than the constructor stuff, you can use class clusters
instead (ie. an "abstract" class _can_ be instantialized, but makes in fact
an instance of an appropriate concrete subclass).
---
Ondra Cada
OCSoftware: email@hidden
http://www.ocs.cz
2K Development: email@hidden
http://www.2kdevelopment.cz
private email@hidden
http://www.ocs.cz/oc