compiled by David Stes (stes@pandora.be)
November 9, 2000
It's posted once a month to comp.lang.objective-c, comp.answers and news.answers. It is archived at ftp://rtfm.mit.edu/pub/faqs/computer-lang/Objective-C/faq.
It's .m for implementation files, and .h for header files. Objective-C compilers usually also accept .c as a suffix, but compile those files in plain C mode.
objcc -c class.m objcc -o class class.o
See http://www.stepstn.com for more information.
cc -c class.m cc -o class class.o
See http://www.apple.com for more information.
gcc -c class.m gcc -o class class.o -lobjc -lpthread
See http://www.gnu.org for more information.
objc -c class.m objc -o class class.o
See http://metalab.unc.edu/pub/Linux/devel/lang/objc/ for more information.
The Objective-C preprocessor usually supports two styles of comments :
// this is a BCPL-style comment (extends to end of line)
and
/* this is a C-style comment */
On Stepstone and the POC, the header file to include is :
<Object.h>
On GNU cc and Apple cc, it's :
<objc/Object.h>
The root class is located in a directory called runtime for the Stepstone compiler, and in a directory called objcrt for the POC, but because of implicit -I options passed on to the preprocessor, these locations are automatically searched.
It's a C preprocessor construct to avoid multiple inclusions of the same file.
#import <Object.h>
is an alternative to
#include <Object.h>
where the .h file is protected itself against multiple inclusions :
#ifndef _OBJECT_H_ ... #define _OBJECT_H_ #endif
The GNU Objective-C compiler emits a warning when you use #import because some people find using #import poor style. You can turn off the warning by using the -Wno-import option, you could modify the compiler source code and set the variable warn_import (in the file cccp.c) or you could convert your code to use pairs of #ifndef and #endif, as shown above, which makes your code work with all compilers.
It's a generic C type that Objective-C uses for an arbitrary object. For example, a static function that takes one object as argument and returns an object, could be declared as :
static id myfunction(id argument) { ... }
self is a variable that refers to the object that received a message in a method implementation. super refers to the same variable, but directs the compiler to use a method implementation from the superclass.
Using pseudo-code, where copy (from super) is the syntax for the copy implementation of the superclass, the following are equivalent :
myObject = [super copy];
and,
myObject = [self copy (from super)]; // pseudo-code
It's a compiler directive to get access to the internal memory layout of instances of a particular class.
typedef struct { @defs(MyClass) } *TMyClass;
defines a C-type TMyClass with a memory layout that is the same as that of MyClass instances.
It's the C type of a message selector; it's often defined as a (uniqued) string of characters (the name of the method, including colons), but not all compilers define the type as such.
perform: is a message to send a message, identified by its message selector (SEL), to an object.
If the name of the method is known at compile time, use @selector :
[myObject perform:@selector(close)];
At runtime, you can lookup the selector by a runtime function that takes the name of the message as argument, as in :
SEL mySel = selUid(name); // for Stepstone SEL mySel = sel_getUid(name); // for Apple SEL mySel = sel_get_any_uid(name); // for GNU Objective C SEL mySel = selUid(name); // for POC
It's the C type of a method implementation pointer, a function pointer to the function that implements an Objective-C method. It is defined to return id and takes two hidden arguments, self and _cmd :
typedef id (*IMP)(id self,SEL _cmd,...);
This can be done by sending a methodFor: message :
IMP myImp = [myObject methodFor:mySel];
By dereferencing the function pointer. The following are all equivalent :
[myObject myMessage];
or
IMP myImp = [myObject methodFor:@selector(myMessage)]; myImp(myObject,@selector(myMessage));
or
[myObject perform:@selector(myMessage)];
For methods that return a C type such as double instead of id, the IMP function pointer is casted from pointer to a function returning id to pointer to a function returning double :
double aDouble = ((double (*) (id,SEL))myImp)(self,_cmd);
No. The method perform: is for sending messages returning id without any other argument. Use perform:with: if the message returns id and takes one argument. Use methodFor: for the general case of any number of arguments and any return type.
copy is intented to make a bytecopy of the object, sharing pointers with the original, and can be overridden to copy additional memory. deepCopy is intented to make a copy that doesn't share pointers with the original. A deep copy of an object contains copies of its instance variables, while a plain copy is normally just a copy at the first level.
You have two options : either use the Apple compiler or use the POC. The former accepts a mix of C++ and Objective-C syntax (called Objective-C++), the latter compiles Objective-C into C and then compiles the intermediate code with a C++ compiler. See the compiler specific questions for more information.
Methods are always implemented in Objective-C as static functions. The only way to obtain the IMP (implementation pointer) of a method is through the runtime (via methodFor: and friends), because the function itself is static to the file that implements the method.
You can't. If your object responds to a message, any other class can send this message. You could add an extra argument sender and check, as in :
- mymethod:sender { if ([sender isKindOf:..]) ... }
But this still requires cooperation of the sender, to use a correct argument :
[anObject mymethod:self];
No, you only have to recompile the implementation of the method itself. Files that only send that particular messages do not have to be recompiled because Objective-C has dynamic binding.
You have to recompile that class, all of its subclasses, and those files that use @defs() or use direct access to the instance variables of that class. In short, using @defs() to access instance variables, or accessing instance variables through subclassing, breaks the encapsulation that the Objective-C runtime normally provides for all other files (the files that you do not have to recompile).
To avoid a conflict between Objective-C's Object and the X11/Object, do the following :
#include <Object.h> #define Object XtObject #include <X11/Intrinsic.h> #include <X11/IntrinsicP.h> #undef Object
To allocate an instance of 'MyClass' on the stack :
MyClass aClass = [MyClass new];
This used to happen on some platforms and is described at ftp://ftp.ics.ele.tue.nl/pub/users/tiggr/objc/README.387. A solution was to add -lieee to the command line, so that an invalid floating point operation in the runtime did not send a signal. DJGPP users can consult http://www.delorie.com/djgpp/v2faq/. AIX users may want to consult http://world.std.com/~
gsk/oc-rs6000-problems.html. In some cases, you can fix the problem by upgrading to a more recent version of the GNU Objective-C runtime and/or compiler.
It's an NXConstantString.
NXConstantString *myString = @"my string";
c++ -c file.m c++ file.o -lcpluslib -o myprogram
List the class variables after the instance variables, and group them together in the same way as instance variables, as follows :
@implementation MyClass : Object { id ivar1; int ivar2; } : { id cvar1; } @end
You have to implement doesNotUnderstand: to send a sentTo: message.
- doesNotUnderstand:aMsg { return [aMsg sentTo:aProxy]; }
objc -c -cplus file.m objc -cplus file.o -lcpluslib -o myprogram
Brad Cox & Andy Novobilski, ISBN 0201548348.
Timothy Budd, ISBN 0201824191
Pinson, Lewis J. / Wiener, Richard S., ISBN 0201508281
Pinson, Lewis J. / Wiener, Richard S., ISBN 0201503697