swarm-support
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Swarm-Support] @class and @public


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
// ...
@end

Then 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

#endif

The 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 header
A.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 dangerous
because 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 you
constantly 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 add
up.  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't
include 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 because
it can't find the o file for the other.  So to fool the compiler, you
promise 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 of
it.

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 confused
about where it is supposed to find methods for myThing.

I say might not because the newest gcc seems to whine and complain and
warn about everything, even stuff we've been doing since before the dawn
of 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've
gleaned from conversations in this list.

pj


Derek Farren wrote:
Hello Swarm friends.
What´s the difference between includeing a Class named Abc by "#include
Abc.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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]