|
From: | Ed Baskerville |
Subject: | Re: [Swarm-Support] @class and @public |
Date: | Wed, 9 Feb 2005 16:47:59 -0800 |
Hi Derek,What Paul said is pretty much right. Essentially, when the preprocessor sees #include A.h, it replaces the #include line with a copy of A.h. If A.h includes B.h and B.h includes A.h, it's easy to see why this becomes a problem very quickly.
Which makes me a bit baffled by your claim that you have circular includes that work. Are you sure it's not the .m files that include the .h files? Can you show us your code?
Side note: in fact, #include doesn't really have anything intrinsically to do with classes except that the convention is to put class declarations in .h files. In plain-old-C land, .h files are typically used to declare functions, constants, etc. that are defined in other (.c) files; class declarations found their way there when Objective-C came into existence.
Another side note: Paul mentioned #import as an alternative to #include. They're similar, but not identical. #include behaves as I mentioned above: it blindly copies the contents of the header file you're including. #import also copies a header file, but it checks to make sure that the file hasn't already been included. This prevents problems from occurring where, say, A.m includes both B.h and C.h, but B.h also includes C.h. (It does not, however, solve the problem of circularity--I'm just mentioning it in case anyone's interested.)
To be wordier but perhaps a little clearer, say A.m looks like this: #include "B.h" #include "C.h" // ... B.h looks like this: #include "C.h" And, finally, C.h looks like this: @interface C // ... @endThen the preprocessor ends putting into A.m a copy of B.h, which in turn gets replaced with a copy of C.h, and then adds another copy of C.h. So A.m, just before compilation, looks like this:
@interface C // ... @end @interface C // ... @end // ...And, justly so, the compiler complains that class C has been declared twice.
#import, on the other hand, checks to see if C.h has already been included before including it again, and you only get one copy of the declaration for class C.
I believe that #import was officially deprecated by the GCC team at one point (you may get compiler warnings with certain versions of GCC for using it), but has since been officially undeprecated. So #import away and save yourself some headaches!
--Ed P.S.There is a way to get around multiple #includes, and this technique is used all the time in the C and C++ world. (You'll also see this in some Objective-C source, such as GNUstep, especially since the GCC team deprecated it.) If you just wrap the file, say, C.h with some more preprocessor code, you accomplish the same thing that #import achieves automatically:
#ifndef __C_H__ #define __C_H__ // Contents of header file here #endifThe choice "__C_H__" is pretty standard--two underscores before and after, and the name of the header file in all caps with the period changed to another underscore. "#ifndef" is C processor shorthand for "if this symbol is not defined." #define means "define this symbol"--note that you can define a symbol's existence without actually giving it a value. And #endif is, well, "end if" in preprocessor land.
This way, if C.h has already been included, __C_H__ will have already been defined, so the entire body of the header file is skipped.
On Feb 9, 2005, at 12:48 PM, Derek Farren wrote:
Thanks Paul.That open an other doubt... I am working with an application where headerA.h imports B.h, and B.h imports A.h. The application compiles without problem. Why is that? Derek ----- Original Message ----- From: "Paul Johnson" <address@hidden> To: "Swarm Support" <address@hidden> Sent: Wednesday, February 09, 2005 9:37 AM Subject: Re: [Swarm-Support] @class and @public@public means an instance variable can be accessed "directly" with -> from outside the object. It essentially makes the object's values accessible as if it were a C struct. It gives quick access to values, but is dangerousbecause you might accidentally change values. By default, IVARS are"private" and the usage like anObject->x will be rejected by the compiler.THe "object oriented religion" holds that people should not write code this way, but sometimes you can get speedups if you avoid it. If youconstantly have to do [anObject getValue] you impose more overead on the runtime than if you have a public variable obtained with anObject -> x. In the Pentium 75 days, a few hundred thousand of those would really addup. But I've not noticed it so much lately :; The #import (or include) includes a header file where a class and its methods are defined. It tells the compiler where to look for methods.If you use @class Abc, you are not really including a class, but you are promising the compiler that you will define it later. THat silences the warnings. This is used as a way to avoid "circular includes". You can'tinclude two h files in each other. Suppose there are 2 classes. A.h A.m B.h B.m In A.h, you want to declare a variable B * myThing;If B.h imports A.h, you can't import B.h in A.h, The compiler is confused because, whichever one gets found first by the compiler will fail becauseit can't find the o file for the other. So to fool the compiler, youpromise it that class will come along later. I recall using that trick in a couple of projects, but I never found a full manual length treatment ofit. The alternative work around is, in A.h, to declare id myThing;and then import B.h in A.m. Then the compiler might not get too confusedabout where it is supposed to find methods for myThing. I say might not because the newest gcc seems to whine and complain andwarn about everything, even stuff we've been doing since before the dawnof time. Or the introduction of the Pentium, which ever came first :)I hope I've not misled you. I'm just giving you back the information I'vegleaned from conversations in this list. pj Derek Farren wrote:Hello Swarm friends.What´s the difference between includeing a Class named Abc by "#includeAbc.h" and @class Abc? Also, what does @public before the definition of a variable mean? Thanks, Derek--------------------------------------------------------------------- ---_______________________________________________ Support mailing list address@hidden http://www.swarm.org/mailman/listinfo/support-- Paul E. Johnson email: address@hidden Dept. of Political Science http://lark.cc.ku.edu/~pauljohn 1541 Lilac Lane, Rm 504 University of Kansas Office: (785) 864-9086 Lawrence, Kansas 66044-3177 FAX: (785) 864-5700 _______________________________________________ Support mailing list address@hidden http://www.swarm.org/mailman/listinfo/support_______________________________________________ Support mailing list address@hidden http://www.swarm.org/mailman/listinfo/support
[Prev in Thread] | Current Thread | [Next in Thread] |