Basic rule: use @class in you header file and #import in your implementation file.
(However, you need to #import your class' superclass. And in some other circumstances you also need to use `#import" in the header.)
#import is not equivalent to #include. If a file is included many times, it will be loaded each time, but with many #imports of the same file, it will still only be loaded once.
Therefore, the main reason to use @class is not to avoid circular dependencies, but to make compilation faster.
Here's an example of when you must use @class
//MYControl.h
@class MYControl;  // Must use class
@protocol MYControlDelegate
-(void)control:(MYControl *)control didChangeToState:(UIControlState)state;
@end
@interface MYControl : UIControl
{
   id<MYControlDelegate> delegate_;
}
@property (nonatomic, assign) id<MYControlDelegate> delegate;
@end
//MYControl.m
@implementation MYControl
@synthesize delegate = delegate_;
. . .
In this case, there is nothing to import, because the delegate protocol is declared above the main class in the header file. But you still need to be able to refer to the main class which has not yet been declared. So what @class does is to just let the compiler know that there is some class that is called MYControl and will be defined at some point. (Not at runtime however. The class will be defined in the course of the compilation.)
EDIT: From the Objective-C manual:
Since declarations like this simply
  use the class name as a type and don’t
  depend on any details of the class
  interface (its methods and instance
  variables), the @class directive gives
  the compiler sufficient forewarning of
  what to expect. However, where the
  interface to a class is actually used
  (instances created, messages sent),
  the class interface must be imported.
  Typically, an interface file uses
  @class to declare classes, and the
  corresponding implementation file
  imports their interfaces (since it
  will need to create instances of those
  classes or send them messages).
The @class directive minimizes the
  amount of code seen by the compiler
  and linker, and is therefore the
  simplest way to give a forward
  declaration of a class name. Being
  simple, it avoids potential problems
  that may come with importing files
  that import still other files. For
  example, if one class declares a
  statically typed instance variable of
  another class, and their two interface
  files import each other, neither class
  may compile correctly.
Note that circularity is mentioned in the last sentence as one in a general class of issues dealt with by using @class.