mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Added objective-c programming manual.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@12373 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
af55de2283
commit
20e890b039
17 changed files with 4282 additions and 0 deletions
|
@ -1,3 +1,11 @@
|
|||
2002-02-01 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Documentation/manual: New directory containing Objective-C and
|
||||
GNUstep-base programming manual/tutorial produced at Brainstorm.
|
||||
The intention was to produce a pretty complete manual and then
|
||||
release it, but we ran out of funding, so I'm releasing the work
|
||||
to date.
|
||||
|
||||
2002-02-01 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/Makefile.preamble: remove old GSI api support
|
||||
|
|
130
Documentation/manual/AdvancedTopics.texi
Normal file
130
Documentation/manual/AdvancedTopics.texi
Normal file
|
@ -0,0 +1,130 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Advanced Topics
|
||||
@chapter Advanced Topics
|
||||
@cindex advanced topics
|
||||
|
||||
@section Forwarding
|
||||
@cindex forwarding
|
||||
|
||||
When an object is unable to respond to a message, the Objective-C
|
||||
runtime sends a @code{forwardInvocation:} message to the object, and
|
||||
the object is then able to use the information provided to handle the
|
||||
message in some way, a common mechanism being to forward the message
|
||||
to another object known as a @b{delegate}, so that the other object
|
||||
can deal with it.
|
||||
|
||||
@example
|
||||
- (void) forwardInvocation: (NSInvocation*)objectInvoke
|
||||
@{
|
||||
if ([forwardObject respondsToSelector: [objectInvoke selector]])
|
||||
return [objectInvoke invokeWithTarget: forwardObject];
|
||||
else
|
||||
return [self doesNotRecognizeSelector: [objectInvoke selector]];
|
||||
@}
|
||||
@end example
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{objectInvoke} is another object (of the @code{NSInvocation} class)
|
||||
which has all the information about the original message sent, including
|
||||
its @b{selector} and its arguments.
|
||||
|
||||
@item
|
||||
@code{self} refers to the object or receiver.
|
||||
@end itemize
|
||||
|
||||
@b{Note. this is a powerful method for creating software patterns for
|
||||
multiple inheritance, journaling, and dispatching messages to
|
||||
dynamically loaded code.}
|
||||
|
||||
@subsection Forwarding and Multiple Inheritance
|
||||
Forwarding is a form of multiple inheritance. The diagram below shows a simple scenario where an instance of the @code{Chat} class passes the @b{negotiate} message to an instance of the @code{ChatTwo} class. The forwarding object therefore inherits methods from its own inheritance path and from that of the receiving object.
|
||||
|
||||
|
||||
|
||||
|
||||
@subsection Surrogate Objects
|
||||
Surrogate objects forward messages to objects that can be assumed to be more complex. The @code{forwardInvocation:} method of the surrogate object receives a message that is to be forwarded; it determines whether or not the receiver exists, and if it does not, then it will attempt to create it. A @b{proxy object} is a common example of a surrogate object. A proxy object performs obvious functions that we have already discussed:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
provides a local address for a remote object
|
||||
|
||||
@item
|
||||
queues messages
|
||||
|
||||
@item
|
||||
forwards messages to typically remote receivers
|
||||
|
||||
@item
|
||||
copies and retrieves arguments over the connection.
|
||||
@end itemize
|
||||
|
||||
|
||||
@subsection Forwarding vs Inheritance
|
||||
The main difference between @b{Forwarding} and @b{Inheritance} surfaces in the application of methods like @code{respondsToSelector} and @code{isKindOfClass:}. This is because these methods search the inheritance path, but ignore the forwarding path.
|
||||
|
||||
(See Section 1.6.6 @code{respondsToSelector.})
|
||||
|
||||
@b{Note. @code{respondsToSelector} does not trace the forwarding chain, and can therefore erroneously report that an object does not respond to a particular message, when it does.}
|
||||
|
||||
|
||||
@comment Making Forwarding Transparent
|
||||
|
||||
|
||||
@section Exception Handling
|
||||
|
||||
|
||||
@section Copying, Comparing, Hashing Objects
|
||||
|
||||
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
deep copy vs swallow copy
|
||||
|
||||
@item
|
||||
simple copy vs mutable copy
|
||||
|
||||
@item
|
||||
isEqual:, hash
|
||||
|
||||
@end itemize
|
||||
|
||||
|
||||
@section Dictionaries, Arrays, Containers
|
||||
|
||||
@section Coding
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Possibilities offered by Coding
|
||||
|
||||
@item
|
||||
Type Encoding
|
||||
|
||||
@end itemize
|
||||
|
||||
|
||||
@section Property Lists
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
What are property lists
|
||||
@end itemize
|
||||
|
||||
|
||||
@section Bundles
|
||||
|
||||
@section UserDefaults
|
||||
|
||||
@section Threading
|
||||
|
||||
General discussion about threading with gnustep base, what is
|
||||
thread-safe, what is not, how to start new threads, NSThread briefly
|
||||
introduced with examples.
|
||||
|
||||
[Nicola: important: talk about NSConnection enableMultipleThreads]].
|
935
Documentation/manual/DistributedObjects.texi
Normal file
935
Documentation/manual/DistributedObjects.texi
Normal file
|
@ -0,0 +1,935 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Distributed Objects
|
||||
@chapter Distributed Objects
|
||||
@cindex distributed objects
|
||||
|
||||
Until now we have been concentrating on using the Objective-C language
|
||||
to create programs that execute in a single process. But what if you
|
||||
want your program to interact with objects in other processes, perhaps
|
||||
running on different machines?
|
||||
|
||||
As a simple example, we may have a client process that needs to access a
|
||||
telephone directory stored on a remote server. The client process could
|
||||
send a message to the server that contained a person's name, and the
|
||||
server could respond by returning that person's number.
|
||||
|
||||
The GNUstep base library provides a powerful set of classes that make
|
||||
this type of remote messaging not only possible, but easy to program. So
|
||||
what do these classes do and how can we use them? To answer that we must
|
||||
first look at the way code interacts with objects in a single process,
|
||||
and then look at how we can achieve the same interaction with objects
|
||||
that exist in different processes.
|
||||
|
||||
@section Object Interaction
|
||||
@cindex object interaction, remote objects
|
||||
|
||||
To continue with the example above, if the telephone directory existed
|
||||
in the same process as the code that was accessing it, then a simple
|
||||
message would return the wanted telephone number.
|
||||
|
||||
@example
|
||||
NSString *wantedNumber = [telephoneDirectory teleNumber: personName];
|
||||
@end example
|
||||
|
||||
Now object and method names just hold pointers to memory addresses. The
|
||||
code executed at run time in response to the @code{teleNumber} message
|
||||
is located at an address held by the name of the responding method (a
|
||||
variable), while data in the telephone directory is located at an
|
||||
address held by the @code{telephoneDirectory} variable.
|
||||
|
||||
In a single process these addresses can be accessed by the client code
|
||||
at run time, but if the telephone directory is located on a remote
|
||||
server, then the address of the remote object is not known in the client
|
||||
process (the @code{telephoneDirectory} object and its responding method
|
||||
are said to exist in a separate 'address space').
|
||||
|
||||
The Objective-C run-time library was not designed for this inter-process
|
||||
communication or 'remote messaging'.
|
||||
|
||||
@section The GNUstep Solution
|
||||
@cindex distributed objects
|
||||
@cindex remote objects
|
||||
@cindex client/server processes
|
||||
@cindex NSConnection class
|
||||
@cindex NSProxy class
|
||||
@cindex NSRunLoop class
|
||||
|
||||
GNUstep overcomes these limitations by providing you with classes that
|
||||
form, what is known as, a 'distributed objects' architecture that
|
||||
extends the capabilities of the run-time system.
|
||||
|
||||
With the addition of a few lines of code in the client and server
|
||||
programs, these extensions allow you to send a message to a remote
|
||||
process by constructing a simple Objective-C statement. In the telephone
|
||||
directory example, the statement to retrieve the telephone number would
|
||||
now look something like this:
|
||||
|
||||
@example
|
||||
NSString *wantedNumber = [proxyForDirectory teleNumber: personName];
|
||||
@end example
|
||||
|
||||
Compare this to the original statement:
|
||||
|
||||
@example
|
||||
NSString *wantedNumber = [telephoneDirectory teleNumber: personName];
|
||||
@end example
|
||||
|
||||
Notice that the only difference between the two statements is the name
|
||||
of the object receiving the message, i.e. @code{proxyForDirectory}
|
||||
rather than @code{telephoneDirectory}. GNUstep makes it as simple as
|
||||
this to communicate with an object in another process.
|
||||
|
||||
The variable @code{proxyForDirectory} is known as a 'proxy' for the
|
||||
remote @code{telephoneDirectory} object. A proxy is simply a substitute
|
||||
for the remote object, with an address in the 'address space' of the
|
||||
local client process, that receives messages and forwards them on to the
|
||||
remote server process in a suitably coded form.
|
||||
|
||||
Let us now take a look at the additional lines of code required to make
|
||||
this 'remote messaging' possible.
|
||||
|
||||
@subsection Code at the Server
|
||||
@cindex server code, GNUstep
|
||||
@cindex GNUstep server code
|
||||
|
||||
In order to respond to client messages, the responding server object
|
||||
must be set as the 'root object' of an instance of the NSConnection
|
||||
class, and this NSConnection must be registered with the network by
|
||||
name. Making an object available to client processes in this way is
|
||||
known as 'vending' the object. The registered name for the NSConnection
|
||||
is used by the client when obtaining a proxy for the responding server
|
||||
object over the network.
|
||||
|
||||
The only other code you need to consider is the code that listens for
|
||||
incoming messages. This 'runloop' as it is known, is started by sending
|
||||
a @code{run} message to an instance of the NSRunLoop class. Since an
|
||||
NSRunLoop object is created automatically for each process, there is no
|
||||
need to create one yourself. Simply get the default runloop, which is
|
||||
returned by the @code{currentRunLoop} class method.
|
||||
|
||||
When the runloop detects an incoming message, the message is passed to
|
||||
the root object of the NSConnection, which performs a method in response
|
||||
to the message and returns a variable of the appropriate type. The
|
||||
NSConnection manages all inter-process communication, decoding incoming
|
||||
messages and encoding any returned values.
|
||||
|
||||
The code to vend the @code{telephoneDirectory} object and start the
|
||||
runloop would look something like this:
|
||||
|
||||
@example
|
||||
/*
|
||||
* Remember, create an instance of the
|
||||
* NSAutoreleasePool class.
|
||||
*/
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
|
||||
/*
|
||||
* Get the default NSConnection object
|
||||
* (a new one is automatically created if none exists).
|
||||
*/
|
||||
NSConnection *connXion = [NSConnection defaultConnection];
|
||||
|
||||
/*
|
||||
* Set the responding server object as
|
||||
* the root object for this connection.
|
||||
*/
|
||||
[connXion setRootObject: telephoneDirectory];
|
||||
|
||||
/*
|
||||
* Try to register a name for the NSConnection,
|
||||
* and report an error if this is not possible.
|
||||
*/
|
||||
if ([connXion registerName: @@"DirectoryServer"] == NO)
|
||||
@{
|
||||
NSLog(@@"Unable to register as 'DirectoryServer'");
|
||||
NSLog(@@"Perhaps another copy of this program is running?");
|
||||
exit(1);
|
||||
@}
|
||||
|
||||
/* Start the current runloop. */
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
|
||||
/* Release the pool */
|
||||
RELEASE(pool);
|
||||
@end example
|
||||
|
||||
These additional lines of code turn a program into a distributed objects
|
||||
server, ready to respond to incoming client messages.
|
||||
|
||||
@subsection Code at the Client
|
||||
@cindex client code, GNUstep
|
||||
@cindex GNUstep client code
|
||||
|
||||
At the client, all you need do is obtain a proxy for the responding
|
||||
server object, using the name that was registered for the NSConnection
|
||||
at the server.
|
||||
|
||||
@example
|
||||
/* Create an instance of the NSAutoreleasePool class */
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
|
||||
/* Get the proxy */
|
||||
id proxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@i{registeredServerName}
|
||||
host: @i{hostName}];
|
||||
|
||||
/* The rest of your program code goes here */
|
||||
|
||||
/* Release the pool */
|
||||
RELEASE(pool);
|
||||
@end example
|
||||
|
||||
The code that obtains the proxy automatically creates an NSConnection
|
||||
object for managing the inter-process communication, so there is no need
|
||||
to create one yourself. If the @i{hostName} in this statement is 'nil',
|
||||
then only the local host will be searched to find the
|
||||
@i{registeredServerName}. If @i{hostName} is "*", then all hosts on the
|
||||
network will be searched.
|
||||
|
||||
In the telephone directory example, the code to obtain the proxy from
|
||||
any host on the network would be:
|
||||
|
||||
@example
|
||||
id proxyForDirectory = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@@"DirectoryServer"
|
||||
host: "*"];
|
||||
@end example
|
||||
|
||||
With this additional line of code in the client program, you can now
|
||||
construct a simple Objective-C statement to communicate with the remote
|
||||
object.
|
||||
|
||||
@example
|
||||
NSString *wantedNumber = [proxyForDirectory teleNumber: personName];
|
||||
@end example
|
||||
|
||||
@subsection Using a Protocol
|
||||
@cindex protocol for distributed objects
|
||||
@cindex distributed objects, using a protocol
|
||||
|
||||
A client process does not need to know the class of a remote server
|
||||
object to avoid run-time errors, it only needs to know the messages to
|
||||
which the remote object responds. This can be determined by the client
|
||||
at run-time, by asking the server if it responds to a particular message
|
||||
before the message is sent.
|
||||
|
||||
If the methods implemented at the server are stated in a formal
|
||||
protocol, then the client can ask the server if it conforms to the
|
||||
protocol, reducing the network traffic required for the individual
|
||||
message/response requests.
|
||||
|
||||
A further advantage is gained at compile time, when the compiler will
|
||||
issue a warning if the server fails to implement any method declared in
|
||||
the protocol, or if the client contains any message to which the server
|
||||
cannot respond.
|
||||
|
||||
The protocol is saved to a header file and then included in both client
|
||||
and server programs with the usual compiler @code{#include}
|
||||
directive. Only the server program needs to implement the methods
|
||||
declared in the protocol. To enable compiler checking in the client
|
||||
program, extend the type declaration for the proxy to this protocol, and
|
||||
cast the returned proxy object to the same extended type.
|
||||
|
||||
In the telephone directory example, if the declared protocol was
|
||||
@code{TelephoneDirectory}, declared in header file
|
||||
@code{protocolHeader.h}, then the client code would now look like this:
|
||||
|
||||
@example
|
||||
#include "protocolHeader.h";
|
||||
|
||||
/* Extend the type declaration */
|
||||
id<TelephoneDirectory> proxyForDirectory;
|
||||
|
||||
/* Cast the returned proxy object to the extended type */
|
||||
proxyForDirectory = (id<TelephoneDirectory>) [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@@"DirectoryServer"
|
||||
host: "*"];
|
||||
@end example
|
||||
Since class names and protocol names do not share the same 'address
|
||||
space' in a process, the declared protocol and the class of the
|
||||
responding server object can share the same name, making code easier to
|
||||
understand.
|
||||
|
||||
For example, @code{proxyForDirectory} at the client could be a proxy for
|
||||
an instance of the @code{TelephoneDirectory} class at the server, and
|
||||
this class could implement the @code{TelephoneDirectory} protocol.
|
||||
|
||||
@section An Example Game Server
|
||||
@cindex distributed objects, example (no error checking)
|
||||
|
||||
It would be tempting to show a complete example of the telephone
|
||||
directory program, but a minimal amount of additional code is required
|
||||
to turn the previous examples into a working implementation. Instead we
|
||||
will look at an example called GameServer that uses distributed objects
|
||||
in a client/server game.
|
||||
|
||||
@i{Exercise: Create a working client/server telephone directory on your
|
||||
own by adding a few lines of code to the previous examples, perhaps with
|
||||
a telephone directory holding only two or three names and numbers. At
|
||||
first you could implement this as a single process and then when it
|
||||
works, modify the code to run as client/server processes running on the
|
||||
same machine. (Try passing the person's name into the client program as
|
||||
a command-line argument. The server need only test the name, e.g. if
|
||||
personName = "Fred" return "number".)}
|
||||
|
||||
@i{All you need do is create two directories, one for the client and one
|
||||
for the server. Each directory will hold a GNUmakefile, the
|
||||
client/server source code, and a copy of the protocol header file. When
|
||||
the files compile, first run the server and then the client. What
|
||||
happens when you run the client without the server? How would you
|
||||
display a "No Server Connection" warning at the client? Appendix B
|
||||
contains a small working example that you can compare with your own
|
||||
implementation.}
|
||||
|
||||
@subsection What GameServer Does
|
||||
@cindex game server example
|
||||
|
||||
Although there is no actual game to play, and while the code to vend an
|
||||
object and connect to a remote process is similar to that already shown,
|
||||
the code does show a number of additional techniques that can be used in
|
||||
other client/server programs.
|
||||
|
||||
@itemize @bullet
|
||||
@item When the client attempts to join the game, the server checks that
|
||||
the client is entitled to join, based on the last time the client
|
||||
played.
|
||||
The rule is: if the client lost the last game, then they cannot re-play
|
||||
for the next 2 hours; but if the client won the last game, then they can
|
||||
re-play the game at any time (a reward for winning).@*@*
|
||||
|
||||
@item The server also makes sure the client is not already connected and
|
||||
playing the game (i.e. they cannot play two games at the same time -
|
||||
that would be cheating).@*@*
|
||||
|
||||
@item In addition to a proxy for the server being obtained at the
|
||||
client, a proxy for the client is received at the server. This allows
|
||||
two-way messaging, where the client can send messages to the server and
|
||||
the server can send messages to the client (e.g. the state of play may
|
||||
be affected by the actions of other players, or by other events at the
|
||||
server).@*@*
|
||||
|
||||
Two protocols will therefore be required, one for the methods
|
||||
implemented at the server and one for those implemented at the client.
|
||||
@end itemize
|
||||
|
||||
Have a look at the program code and added comments. Can you work out
|
||||
what is happening at the server and client? If you have any difficulties
|
||||
then refer to the relevant sections in this manual, or to class
|
||||
documentation at the GNUstep or Apple web-sites.
|
||||
|
||||
@subsection Protocol Adopted at Client
|
||||
|
||||
We have chosen @code{GameClient} as the name of both the protocol
|
||||
adopted at the client and the class of the responding client object. The
|
||||
header file declaring this protocol will simply declare the methods that
|
||||
the class must implement.
|
||||
|
||||
@example
|
||||
@@protocol GameClient
|
||||
- (void) clientMessage: (bycopy NSString *)theMessage;
|
||||
- (int) clientReply;
|
||||
|
||||
// Other methods would be added that
|
||||
// reflect the nature of the game.
|
||||
|
||||
@@end
|
||||
@end example
|
||||
|
||||
The protocol will be saved as @code{GameClient.h}.
|
||||
|
||||
@subsection Protocol Adopted at Server
|
||||
|
||||
We have chosen @code{GameServer} as the name of both the protocol
|
||||
adopted at the server and the class of the responding server object. The
|
||||
header file declaring this protocol will simply declare the methods that
|
||||
the class must implement.
|
||||
|
||||
@example
|
||||
@@protocol GameServer
|
||||
- (BOOL) mayJoin: (id)client asPlayer: (bycopy NSString*)name;
|
||||
- (int) startGame: (bycopy NSString*)name;
|
||||
- (BOOL) endGame: (bycopy NSString*)name;
|
||||
|
||||
// Other methods would be added that
|
||||
// reflect the nature of the game.
|
||||
|
||||
@@end
|
||||
@end example
|
||||
|
||||
The protocol will be saved as @code{GameServer.h}.
|
||||
|
||||
@subsection Code at the Client
|
||||
|
||||
The client code contains the @code{main} function and the
|
||||
@code{GameClient} class declaration and implementation.
|
||||
|
||||
The @code{main()} function attempts to connect to the server, while the
|
||||
@code{GameClient} class adopts the @code{GameClient} protocol.
|
||||
|
||||
@example
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "GameServer.h"
|
||||
#include "GameClient.h"
|
||||
|
||||
/*
|
||||
* GameClient class declaration:
|
||||
* Adopt the GameClient protocol.
|
||||
*/
|
||||
@@interface GameClient : NSObject <GameClient>
|
||||
@@end
|
||||
|
||||
/*
|
||||
* GameClient class implementation.
|
||||
*/
|
||||
@@implementation GameClient
|
||||
|
||||
/*
|
||||
* Implement clientMessage: as declared in the protocol.
|
||||
* The method simply prints a message at the client.
|
||||
*/
|
||||
- (void) clientMessage: (NSString*)theMessage
|
||||
@{
|
||||
printf([theMessage cString]);
|
||||
@}
|
||||
|
||||
/*
|
||||
* Implement clientReply: as declared in the protocol.
|
||||
* The method simply returns the character entered
|
||||
* at the client keyboard.
|
||||
*/
|
||||
- (int) clientReply
|
||||
@{
|
||||
return getchar();
|
||||
@}
|
||||
@@end // End of GameClient class implementation.
|
||||
|
||||
/*
|
||||
* The main function of the client program.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
@{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
id<GameServer> server;
|
||||
int result;
|
||||
NSString *name;
|
||||
id client;
|
||||
|
||||
/*
|
||||
* The NSUserName() function returns the name of the
|
||||
* current user, which is sent to the server when we
|
||||
* try to join the game.
|
||||
*/
|
||||
name = NSUserName();
|
||||
|
||||
/*
|
||||
* Create a GameClient object that is sent to
|
||||
* the server when we try to join the game.
|
||||
*/
|
||||
client = AUTORELEASE([GameClient new]);
|
||||
|
||||
/*
|
||||
* Try to get a proxy for the root object of a server
|
||||
* registered under the name 'JoinGame'. Since the host
|
||||
* is '*', we can connect to any server on the local network.
|
||||
*/
|
||||
server = (id<GameServer>)[NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@@"JoinGame" host: @@"*"];
|
||||
if(server == nil)
|
||||
@{
|
||||
printf("\n** No Connection to GameServer **\n");
|
||||
result = 1;
|
||||
@}
|
||||
|
||||
/*
|
||||
* Try to join the game, passing a GameClient object as
|
||||
* the client, and our user-name as name. The 'client'
|
||||
* argument will be received as a proxy at the server.
|
||||
*/
|
||||
else if ([server mayJoin: client asPlayer: name] == NO)
|
||||
@{
|
||||
result = 1; // We cannot join the game.
|
||||
@}
|
||||
else
|
||||
@{
|
||||
/*
|
||||
* At this point, we would actually start to play the game.
|
||||
*/
|
||||
[server startGame: name]; // Start playing game.
|
||||
[server endGame: name]; // Finally end the game.
|
||||
result = 0;
|
||||
@}
|
||||
RELEASE(pool);
|
||||
return result;
|
||||
@}
|
||||
@end example
|
||||
|
||||
To summarise the code at the client:
|
||||
|
||||
@itemize @bullet
|
||||
@item We obtained a proxy for the server and can now communicate
|
||||
with the server using the methods declared in the @code{GameServer}
|
||||
protocol.@*@*
|
||||
|
||||
@item We passed a @code{GameClient} object and our user-name to the
|
||||
server (the @code{GameClient} object is received as a proxy at the
|
||||
server). The server can now communicate with the client using the
|
||||
methods declared in the @code{GameClient} protocol.@*@*
|
||||
|
||||
@item When the game is in progress, the server can alter the state
|
||||
of the client object to reflect the success of the player.
|
||||
@end itemize
|
||||
|
||||
@subsection Code at the Server
|
||||
|
||||
The server code contains the @code{main} function and the
|
||||
@code{GameServer} class declaration and implementation.
|
||||
|
||||
The @code{main()} function vends the server's root object and starts the
|
||||
runloop, while the @code{GameServer} class adopts the @code{GameServer}
|
||||
protocol. The class also implements methods that initialise and
|
||||
deallocate the root object's instance variables (dictionaries that hold
|
||||
player information).
|
||||
|
||||
@example
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "GameServer.h"
|
||||
#include "GameClient.h"
|
||||
|
||||
/*
|
||||
* GameServer class declaration:
|
||||
* Adopt the GameServer protocol and declare
|
||||
* GameServer instance variables.
|
||||
*/
|
||||
@@interface GameServer : NSObject <GameServer>
|
||||
@{
|
||||
NSMutableDictionary *delayUntil; // Delays to re-joining GameServer.
|
||||
NSMutableDictionary *currentPlayers; // Proxies to each client.
|
||||
NSMutableDictionary *hasWon; // Success in game for each player.
|
||||
@}
|
||||
@@end
|
||||
|
||||
/*
|
||||
* GameServer class implementation.
|
||||
*/
|
||||
@@implementation GameServer
|
||||
|
||||
/* Initialise GameServer's instance variables. */
|
||||
- (id) init
|
||||
@{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
@{
|
||||
/*
|
||||
* Create a dictionary for a maximum of
|
||||
* 10 named players that will hold a
|
||||
* re-joining time delay.
|
||||
*/
|
||||
delayUntil = [[NSMutableDictionary alloc]
|
||||
initWithCapacity: 10];
|
||||
/*
|
||||
* Create a dictionary that will hold the
|
||||
* names of these players and a proxy for
|
||||
* the received client objects.
|
||||
*/
|
||||
currentPlayers = [[NSMutableDictionary alloc]
|
||||
initWithCapacity: 10];
|
||||
|
||||
/*
|
||||
* Create a dictionary that will record
|
||||
* a win for any of these named players.
|
||||
*/
|
||||
hasWon = [[NSMutableDictionary alloc]
|
||||
initWithCapacity: 10];
|
||||
@}
|
||||
return self;
|
||||
@}
|
||||
|
||||
/* Release GameServer's instance variables. */
|
||||
- (void) dealloc
|
||||
@{
|
||||
RELEASE(delayUntil);
|
||||
RELEASE(currentPlayers);
|
||||
RELEASE(hasWon);
|
||||
[super dealloc];
|
||||
@}
|
||||
|
||||
/*
|
||||
* Implement mayJoin:: as declared in the protocol.
|
||||
* Adds the client to the list of current players.
|
||||
* Each player is represented at the server by both
|
||||
* name and by proxy to the received client object.
|
||||
* A player cannot join the game if they are already playing,
|
||||
* or if joining has been delayed until a later date.
|
||||
*/
|
||||
- (BOOL) mayJoin: (id)client asPlayer: (NSString*)name
|
||||
@{
|
||||
NSDate *delay; // The time a player can re-join the game.
|
||||
NSString *aMessage;
|
||||
|
||||
if (name == nil)
|
||||
@{
|
||||
NSLog(@@"Attempt to join nil user");
|
||||
return NO;
|
||||
@}
|
||||
|
||||
/* Has the player already joined the game? */
|
||||
if ([currentPlayers objectForKey: name] != nil)
|
||||
@{
|
||||
/* Inform the client that they cannot join. */
|
||||
aMessage = @@"\nSorry, but you are already playing GameServer!\n";
|
||||
[client clientMessage: aMessage];
|
||||
return NO;
|
||||
@}
|
||||
|
||||
/* Get the player's time delay for re-joining. */
|
||||
delay = [delayUntil objectForKey: name];
|
||||
|
||||
/*
|
||||
* Can the player join the game? Yes if there is
|
||||
* no restriction or if the time delay has passed;
|
||||
* otherwise no, they cannot join.
|
||||
*/
|
||||
if (delay == nil || [delay timeIntervalSinceNow] <= 0.0)
|
||||
@{
|
||||
/* Remove the old restriction on re-joining the game. */
|
||||
[delayUntil removeObjectForKey: name];
|
||||
|
||||
/* Add the player to the list of current players. */
|
||||
[currentPlayers setObject: client forKey: name];
|
||||
[hasWon setObject: @@"NO" forKey: name]; // They've not won yet.
|
||||
|
||||
/* Inform the client that they have joined the game. */
|
||||
aMessage = @@"\nWelcome to GameServer\n";
|
||||
[client clientMessage: aMessage];
|
||||
return YES;
|
||||
@}
|
||||
else
|
||||
@{
|
||||
/* Inform the client that they cannot re-join. */
|
||||
aMessage = @@"\nSorry, you cannot re-join GameServer yet.\n";
|
||||
[client clientMessage: aMessage];
|
||||
return NO;
|
||||
@}
|
||||
@}
|
||||
|
||||
/*
|
||||
* Implement startGame: as declared in the protocol.
|
||||
* Simply ask the player if they want to win, and get
|
||||
* there reply.
|
||||
*/
|
||||
- (int) startGame: (NSString *)name
|
||||
@{
|
||||
NSString *aMessage;
|
||||
id client;
|
||||
int reply;
|
||||
|
||||
client = [currentPlayers objectForKey: name];
|
||||
|
||||
aMessage = @@"\nDo you want to win this game? (Y/N <RET>) ... ";
|
||||
[client clientMessage: aMessage];
|
||||
|
||||
reply = [client clientReply];
|
||||
if(reply == 'y' || reply == 'Y')
|
||||
[hasWon setObject: @@"YES" forKey: name]; // They win.
|
||||
else [hasWon setObject: @@"NO" forKey: name]; // They loose.
|
||||
return 0;
|
||||
@}
|
||||
|
||||
/*
|
||||
* Implement endGame: as declared in the protocol.
|
||||
* Removes a player from the game, and either sets
|
||||
* a restriction on the player re-joining or removes
|
||||
* the current restriction.
|
||||
*/
|
||||
- (BOOL) endGame: (NSString*)name
|
||||
@{
|
||||
id client;
|
||||
NSString *aMessage, *yesOrNo;
|
||||
NSDate *now, *delay;
|
||||
NSTimeInterval twoHours = 2 * 60 * 60; // Seconds in 2 hours.
|
||||
|
||||
if (name == nil)
|
||||
@{
|
||||
NSLog(@@"Attempt to end nil user");
|
||||
return NO;
|
||||
@}
|
||||
|
||||
now = [NSDate date];
|
||||
delay = [now addTimeInterval: twoHours];
|
||||
client = [currentPlayers objectForKey: name];
|
||||
yesOrNo = [hasWon objectForKey: name];
|
||||
|
||||
if ([yesOrNo isEqualToString: @@"YES"]) // Has player won?
|
||||
@{
|
||||
/*
|
||||
* Player wins, no time delay to re-joining the game.
|
||||
* Remove any re-joining restriction and send
|
||||
* a message to the client.
|
||||
*/
|
||||
[delayUntil removeObjectForKey: name];
|
||||
aMessage = @@"\nWell played: you can re-join GameServer at any time.\n";
|
||||
[client clientMessage: aMessage];
|
||||
|
||||
@}
|
||||
else // Player lost
|
||||
@{
|
||||
/*
|
||||
* Set a time delay for re-joining the game,
|
||||
* and send a message to the client.
|
||||
*/
|
||||
[delayUntil setObject: delay forKey: name];
|
||||
aMessage = @@"\nYou lost, but you can re-join GameServer in 2 hours.\n";
|
||||
[client clientMessage: aMessage];
|
||||
@}
|
||||
|
||||
/* Remove the player from the current game. */
|
||||
[currentPlayers removeObjectForKey: name];
|
||||
[hasWon removeObjectForKey: name];
|
||||
return YES;
|
||||
@}
|
||||
|
||||
@@end // End of GameServer class implementation
|
||||
|
||||
/*
|
||||
* The main function of the server program simply
|
||||
* vends the root object and starts the runloop.
|
||||
*/
|
||||
int main(int argc, char** argv)
|
||||
@{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
GameServer *server;
|
||||
NSConnection *connXion;
|
||||
|
||||
server = AUTORELEASE([GameServer new]);
|
||||
connXion = [NSConnection defaultConnection];
|
||||
[connXion setRootObject: server];
|
||||
[connXion registerName: @@"JoinGame"];
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
RELEASE(pool);
|
||||
return 0;
|
||||
@}
|
||||
@end example
|
||||
|
||||
To summarise the code at the server:
|
||||
|
||||
@itemize @bullet
|
||||
@item We vend the server's root object and start a runloop,
|
||||
allowing clients to connect with the server.@*@*
|
||||
|
||||
@item When we receive a proxy for a client object, we communicate
|
||||
with that client using methods declared in the @code{ClientServer}
|
||||
protocol.@*@*
|
||||
|
||||
@item We create three dictionary objects, each referenced by player
|
||||
name. @code{currentUsers} holds proxies for each of the current
|
||||
players; @code{delayUntil} holds times when each player can re-join
|
||||
the game; and @code{hasWon} holds a string for each player, which is
|
||||
set to "YES" if the player wins.@*@*
|
||||
|
||||
@item When the game is in progress, the server can alter the state of
|
||||
each client object to reflect the success of each player.
|
||||
@end itemize
|
||||
|
||||
I hope you managed to understand most of the code in this example. If
|
||||
you are reading the on-screen version, then you can copy and paste the
|
||||
code to suitably named files, create makefiles, and then make and run
|
||||
each program. What message is displayed if you immediately try to
|
||||
re-join a game after loosing? And after winning?
|
||||
|
||||
@i{Exercise: Modify the server code so that the server records the
|
||||
number of wins for each player, and displays this information at both
|
||||
the start and end of each game.}
|
||||
|
||||
@section Language Support for Distributed Objects
|
||||
|
||||
Objective-C provides special 'type' qualifiers that can be used in a
|
||||
protocol to control the way that message arguments are passed between
|
||||
remote processes, while at run time, the run-time system transparently
|
||||
uses what is known as 'forward invocation' to forward messages to a
|
||||
remote process.
|
||||
|
||||
@subsection Protocol Type Qualifiers
|
||||
@cindex protocol type qualifiers
|
||||
@cindex in, out, and inout type qualifiers
|
||||
@cindex out, type qualifier
|
||||
@cindex oneway, type qualifier
|
||||
@cindex bycopy and byref type qualifiers
|
||||
When message arguments are passed by value then the receiving method can
|
||||
only alter the copy it receives, and not the value of the original
|
||||
variable. When an argument is passed by reference (as a pointer), the
|
||||
receiving method has access to the original variable and can alter that
|
||||
variable's data. In this case the argument is effectively passed 'in' to
|
||||
the method, and then passed 'out' of the method (on method return).
|
||||
|
||||
When an argument is passed by reference to a remote object, the network
|
||||
must handle this two-way traffic, whether or not the remote object
|
||||
modifies the received argument.
|
||||
|
||||
Type qualifiers can be used in a protocol to control the way these
|
||||
messages are handled, and to indicate whether or not the sending process
|
||||
will wait for the remote process to return.
|
||||
|
||||
@itemize @bullet
|
||||
@item The @b{oneway} qualifier is used in conjunction with a
|
||||
@code{void} return type to inform the run-time system that the sending
|
||||
process does not need to wait for the receiving method to return (known
|
||||
as 'asynchronous' messaging). The protocol declaration for the receiving
|
||||
method would look something like this:@*@*
|
||||
|
||||
@code{- (@b{oneway} void)noWaitForReply;}@*@*
|
||||
|
||||
@item The @b{in, out } and @b{inout} qualifiers can be used with pointer
|
||||
arguments to control the direction in which an argument is passed. The
|
||||
protocol declaration for the receiving methods would look something like
|
||||
this:@*
|
||||
|
||||
@example
|
||||
/*
|
||||
* The value that 'number' points to will be passed @b{in} to the remote process.
|
||||
* (No need to return the argument's value from the remote process.)
|
||||
*/
|
||||
@code{- setValue: (@b{in} int *)number;}
|
||||
|
||||
/*
|
||||
* The value that 'number' points to will be passed @b{out} of the remote process.
|
||||
* (No need to send the argument's value to the remote process.)
|
||||
*/
|
||||
@code{- getValue: (@b{out} int *)number;}
|
||||
|
||||
/*
|
||||
* The value that 'number' points to is first passed @b{in} to the remote
|
||||
* process, but will eventually be the value that is passed @b{out} of the
|
||||
* remote process. (Send and return the argument's value.)
|
||||
*/
|
||||
@code{- changeValue: (@b{inout} int *)number;}
|
||||
@end example
|
||||
|
||||
|
||||
@item The @b{bycopy} and @b{byref} qualifiers can be used in a protocol
|
||||
when the argument or return type is an object.@*@*
|
||||
|
||||
An object is normally passed by reference and received in the remote
|
||||
process as a proxy. When an object is passed by copy, then a copy of
|
||||
the object will be received in the remote process, allowing the remote
|
||||
process to directly interact with the copy. Protocol declarations would
|
||||
look something like this:@*
|
||||
|
||||
@example
|
||||
/*
|
||||
* Copy of object will be received in the remote process.
|
||||
*/
|
||||
- sortNames: (@b{bycopy} id)listOfNames;
|
||||
|
||||
/*
|
||||
* Copy of object will be returned by the remote process.
|
||||
*/
|
||||
- (@b{bycopy} id)returnNames;
|
||||
@end example
|
||||
|
||||
By default, large objects are normally sent @b{byref}, while small
|
||||
objects like @code{NSStrings} are normally sent @b{bycopy}, but you
|
||||
cannot rely on these defaults being adopted and should explicitly state
|
||||
the qualifier in the protocol.@*@*
|
||||
|
||||
|
||||
The @b{bycopy} qualifier can also be used in conjunction with the
|
||||
@b{out} qualifier, to indicate that an object will be passed @b{out} of
|
||||
the remote process by copy rather than by proxy (no need to send the
|
||||
object).@*
|
||||
|
||||
@example
|
||||
/*
|
||||
* The object will not be received in the remote process, but the object
|
||||
* will be returned @b{bycopy}.
|
||||
*/
|
||||
- sortAndReturn: (@b{bycopy out} id *)listOfNames;
|
||||
@end example
|
||||
|
||||
You should be aware that some classes ignore the @b{bycopy} qualifier
|
||||
and the object will be sent by reference. The @b{bycopy} qualifier will
|
||||
also be ignored if the remote process does not have the class of the
|
||||
object in its address space, since an object's instance variables are
|
||||
accessed through the object's methods.@*@*
|
||||
|
||||
When a copy of an object is sent to a remote process, only the object's
|
||||
instance variables are sent and received (an object's methods exist in
|
||||
the address space of the object's class, not in the address space of the
|
||||
individual object).
|
||||
|
||||
@end itemize
|
||||
|
||||
@subsection Message Forwarding
|
||||
@cindex message forwarding, distributed objects
|
||||
@cindex forward invocation, distributed objects
|
||||
When a proxy forwards a message to a remote object, the GNUstep run-time
|
||||
extensions automatically implement what is known as 'forward
|
||||
invocation'. At run-time, the message received at the proxy is
|
||||
automatically re-packaged and sent to the proxy's
|
||||
@code{forwardInvocation:} method. This method determines whether or not
|
||||
a remote object exists that can respond to the received message,
|
||||
forwarding the message on (or not), depending on the reply.@*
|
||||
|
||||
While this handling of messages by the proxy is transparent to the
|
||||
distributed objects programmer, any object can implement forward
|
||||
invocation, allowing it to pass on messages for which it has no
|
||||
responding method. Forward invocation is discussed in more detail in the
|
||||
next chapter.
|
||||
|
||||
|
||||
@section Error Checking
|
||||
@cindex error checking, distributed objects
|
||||
@cindex distributed objects, error checking
|
||||
|
||||
When dealing with distributed objects your code must be able to handle
|
||||
the following situations: failure to vend the server object, exceptions
|
||||
raised at run-time, and failure of the network connection.
|
||||
|
||||
@subsection Vending the Server Object
|
||||
When vending the server object, your code must be able to handle the
|
||||
situation in which the network does not accept the proposed registered
|
||||
name for the server.
|
||||
|
||||
@subsection Catching Exceptions
|
||||
There are two situations to consider.
|
||||
@itemize @bullet
|
||||
@item An @code{NSPortTimeoutException} is raised.@*@*
|
||||
This exception is raised if a message takes too long to arrive at the
|
||||
remote process, or if a reply takes too long to return. This will happen
|
||||
if the remote process is busy, has hung, or if there is a problem with
|
||||
the network. The best way to handle the exception is to close the
|
||||
connection to the remote process.@*@*
|
||||
|
||||
@item An exception is raised in the remote process while the remote
|
||||
process is executing a method.@*@*
|
||||
In most cases you can deal directly with these exceptions in the process
|
||||
in which they were raised; i.e. without having to consider the network
|
||||
connection itself.
|
||||
@end itemize
|
||||
|
||||
@subsection The Connection Fails
|
||||
You can register an observer object to receive a notification, in the
|
||||
form of a @code{connectionDidDie} message, when a registered connection
|
||||
fails. The argument to this message will be an @code{NSNotification}
|
||||
object that returns the failed connection when it receives an
|
||||
@code{object} message.
|
||||
|
||||
To receive this 'notification' the observer must implement the
|
||||
@code{connectionDidDie} method, but can be an instance of any class. The
|
||||
observer can then handle the failure gracefully, by releasing any
|
||||
references to the failed connection and releasing proxies that used the
|
||||
connection. Registering an object to receive this notification is
|
||||
described in more detail in the @code{NSConnection} class documentation.
|
||||
|
||||
@subsection GameServer Example with Error Checking
|
||||
|
||||
Earlier on in this section we looked at an example client/server program
|
||||
called GameServer, and you will find a further example of this program,
|
||||
with additional error checking, in Appendix B.
|
||||
|
||||
|
||||
|
185
Documentation/manual/ExampleCode.texi
Normal file
185
Documentation/manual/ExampleCode.texi
Normal file
|
@ -0,0 +1,185 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Examples
|
||||
@appendix Example Objective-C Code
|
||||
@cindex example Objective-C code
|
||||
|
||||
@c /* Add example code to this file as it becomes available */
|
||||
|
||||
|
||||
@section A Simple Telephone Directory
|
||||
|
||||
In the 'Distributed Objects' chapter, it was left as an exercise to
|
||||
prepare code for a simple client/server telephone directory. Below is
|
||||
one implementation that you can compare with your own version.
|
||||
|
||||
If you are reading the on-screen version of this manual, then you can
|
||||
copy and paste the code to suitably named files, and then make and run
|
||||
each program. The directory only stores the telephone numbers of two
|
||||
people: Jack and Jill.
|
||||
|
||||
To use the telephone directory first run the server and then the client,
|
||||
passing either Jack or Jill as a command line argument. If you pass any
|
||||
other name then the number will be displayed as 'Number not found'.
|
||||
|
||||
@subsection The Makefiles
|
||||
|
||||
@example
|
||||
# The Client makefile, saved as GNUmakefile
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
TOOL_NAME = RunClient
|
||||
RunClient_OBJC_FILES = Client.m
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/tool.make
|
||||
# End of client makefile
|
||||
|
||||
# The Server makefile, saved as GNUmakefile
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
TOOL_NAME = RunServer
|
||||
RunServer_OBJC_FILES = Server.m
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/tool.make
|
||||
# End of server makefile
|
||||
@end example
|
||||
|
||||
@subsection The Protocol Header File
|
||||
|
||||
@example
|
||||
/*
|
||||
* TelephoneDirectory protocol, saved as TelephoneDirectory.h.
|
||||
* This file must be included at both client and server.
|
||||
*/
|
||||
@@protocol TelephoneDirectory
|
||||
- (char *) teleNumber: (char *)personName;
|
||||
@@end
|
||||
@end example
|
||||
|
||||
@subsection Code at the Client
|
||||
|
||||
@example
|
||||
/*
|
||||
* This #include line is generally present in all Objective-C
|
||||
* source files that use GNUstep. The Foundation.h header file
|
||||
* includes all the other standard header files you need.
|
||||
*/
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
/* Include the TelephoneDirectory protocol header file */
|
||||
#include "TelephoneDirectory.h"
|
||||
|
||||
/*
|
||||
* The main() function: Get the telephone number for
|
||||
* 'personName' from the server registered as 'DirectoryServer'.
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
@{
|
||||
char *personName = argv[1];
|
||||
char *returnedNumber;
|
||||
id<TelephoneDirectory> proxyForDirectory;
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
|
||||
proxyForDirectory = (id<TelephoneDirectory>) [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@@"DirectoryServer"
|
||||
host: @@"*"];
|
||||
|
||||
if(proxyForDirectory == nil)
|
||||
printf("\n** WARNING: NO CONNECTION TO SERVER **\n");
|
||||
else printf("\n** Connected to server **\n");
|
||||
|
||||
if(argc == 2) // Command line name entered
|
||||
@{
|
||||
returnedNumber = (char *)[proxyForDirectory teleNumber: personName];
|
||||
printf("\n%s%s%s%s%s\n", "** (In client) The telephone number for ",
|
||||
personName, " is:",
|
||||
returnedNumber, " **");
|
||||
@}
|
||||
else printf("\n** No name entered **\n");
|
||||
printf("\n%s\n\n", "** End of client program **");
|
||||
RELEASE(pool);
|
||||
return 0;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@subsection Code at the Server
|
||||
|
||||
@example
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
/* Include the TelephoneDirectory protocol header file */
|
||||
#include "TelephoneDirectory.h"
|
||||
|
||||
/*
|
||||
* Declare the TelephoneDirectory class that
|
||||
* implements the 'teleNumber' instance method.
|
||||
*/
|
||||
@@interface TelephoneDirectory : NSObject <TelephoneDirectory>
|
||||
@@end
|
||||
|
||||
/*
|
||||
* Define the TelephoneDirectory class
|
||||
* and the instance method (teleNumber).
|
||||
*/
|
||||
@@implementation TelephoneDirectory : NSObject
|
||||
- (char *) teleNumber: (char *) personName
|
||||
@{
|
||||
if (strcmp(personName, "Jack") == 0) return " 0123 456";
|
||||
else if (strcmp(personName, "Jill") == 0) return " 0456 789";
|
||||
else return " Number not found";
|
||||
@}
|
||||
@@end
|
||||
|
||||
/*
|
||||
* The main() function: Set up the program
|
||||
* as a 'Distibuted Objects Server'.
|
||||
*/
|
||||
int main(void)
|
||||
@{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
|
||||
/* Declare and define the telephoneDirectory object */
|
||||
TelephoneDirectory *teleDirectory = [[TelephoneDirectory alloc] init];
|
||||
|
||||
/*
|
||||
* Get the default NSConnection object,
|
||||
* or create a new one if none exists.
|
||||
*/
|
||||
NSConnection *connXion = [NSConnection defaultConnection];
|
||||
|
||||
/*
|
||||
* Set the responding server object to be
|
||||
* the root object for this connection.
|
||||
*/
|
||||
[connXion setRootObject: teleDirectory];
|
||||
|
||||
/*
|
||||
* Try to register a name for the NSConnection,
|
||||
* and report an error if this is not possible.
|
||||
*/
|
||||
if ([connXion registerName: @@"DirectoryServer"] == NO)
|
||||
@{
|
||||
NSLog(@@"Unable to register as 'DirectoryServer'");
|
||||
NSLog(@@"Perhaps another copy of this program is running?");
|
||||
exit(1);
|
||||
@}
|
||||
else NSLog(@@"\n** Managed to register connection as 'DirectoryServer' **\n");
|
||||
|
||||
/* Start the current runloop. */
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
|
||||
RELEASE(pool);
|
||||
return 0;
|
||||
@}
|
||||
@end example
|
||||
|
||||
|
||||
@section GameServer with Error Checking
|
||||
|
||||
In the 'Distributed Objects' chapter, code was listed at the client and
|
||||
server for an example GameServer. The code is reproduced here, but with
|
||||
additional error checking for: failure to vend the server object,
|
||||
exceptions raised at run-time, and failure of the network connection.
|
||||
|
||||
*** Code to be added here ***
|
27
Documentation/manual/GNUmakefile
Normal file
27
Documentation/manual/GNUmakefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
GNUSTEP_MAKEINFO_FLAGS = -D NO-TEXI2HTML
|
||||
|
||||
DOCUMENT_NAME = manual
|
||||
|
||||
manual_TEXI_FILES = \
|
||||
manual.texi \
|
||||
foreword.texi \
|
||||
Introduction.texi \
|
||||
ObjcLanguage.texi \
|
||||
WritingNewClasses.texi \
|
||||
WorkingWithObjects.texi \
|
||||
DistributedObjects.texi \
|
||||
AdvancedTopics.texi \
|
||||
Glossary.texi \
|
||||
ExampleCode.texi \
|
||||
GNUstepMake.texi \
|
||||
ObjcAndJava.texi \
|
||||
JavaAndGuile.texi
|
||||
|
||||
manual_DOC_INSTALL_DIR = Developer/Base/ProgrammingManual
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/documentation.make
|
||||
|
||||
|
226
Documentation/manual/GNUstepMake.texi
Normal file
226
Documentation/manual/GNUstepMake.texi
Normal file
|
@ -0,0 +1,226 @@
|
|||
@node Make
|
||||
@appendix Using the GNUstep Make Package
|
||||
@cindex GNUstep Make package
|
||||
@cindex Make package, GNUstep
|
||||
|
||||
Reference/doc on the GNUstep make package; mainly examples of various
|
||||
types of projects.
|
||||
|
||||
@section Makefile Contents
|
||||
@paragraphindent 0
|
||||
|
||||
@b{Note. Type @code{man make} for assistance.}
|
||||
|
||||
Make files comprise four key content types:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@b{Comments}
|
||||
|
||||
@code{#} prefixes comments.
|
||||
|
||||
@item
|
||||
@b{Macros}
|
||||
|
||||
@code{SRC=main.m} assigns a macro that is implemented as:@code{gcc $(SRC)}
|
||||
and is interpreted as:
|
||||
@code{gcc main.m}
|
||||
|
||||
@item
|
||||
@b{Explicit rules}
|
||||
Explicit rules are used to indicate which files depend upon supporting files and
|
||||
the commands required for their compilation:
|
||||
@example
|
||||
targetfile : sourcefiles
|
||||
commands
|
||||
@end example
|
||||
|
||||
A Tab precedes each command that must be implemented on the source files in order
|
||||
to create the target file:
|
||||
@example
|
||||
main: main.m List.h
|
||||
gcc -o main main.m List.h
|
||||
@end example
|
||||
|
||||
@item
|
||||
@b{Implicit rules}
|
||||
Implicit rules broadly echo explicit variants but do not specify commands, rather the
|
||||
extensions indicate which commands are performed:
|
||||
|
||||
@code{servertest.o: servertest.c io.h}
|
||||
@*
|
||||
is interpreted as:
|
||||
@*
|
||||
@code{$(CC) $(CFLAGS) -c servertest.c io.h}
|
||||
@end itemize
|
||||
|
||||
@subsection Makefile Example
|
||||
|
||||
@example
|
||||
# The following two lines force the standard make to recognize the
|
||||
# Objective-C .m suffix.
|
||||
|
||||
.SUFFIXES: .o .m
|
||||
.m.o:
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
|
||||
# Macro declarations
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g
|
||||
LIBS = -lobjc
|
||||
SRC=main.m Truck.m Station.m Vehicle.m
|
||||
OBJ=main.o Truck.o Station.o Vehicle.o
|
||||
|
||||
|
||||
# Explicit rules
|
||||
|
||||
hist: $(OBJ)
|
||||
$(CC) $(CFLAGS) -o main $(OBJ) $(LIBS)
|
||||
|
||||
|
||||
# Implicit rules
|
||||
|
||||
Truck.o: Truck.h Truck.m
|
||||
Station.o: Truck.h Station.h Station.m
|
||||
Vehicle.o: Truck.h Vehicle.h Vehicle.m
|
||||
main.o: Station.h Vehicle.h
|
||||
|
||||
@end example
|
||||
|
||||
|
||||
@subsection Makefile Structure
|
||||
|
||||
The following Makefile defines a project:
|
||||
|
||||
@example
|
||||
#
|
||||
# A GNUmakefile
|
||||
#
|
||||
|
||||
# Include the common variables
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
# Build an Objective-C program
|
||||
OBJC_PROGRAM_NAME = simple
|
||||
|
||||
# Objective-C files requiring compilation
|
||||
simple_OBJC_FILES = simple.m
|
||||
|
||||
-include GNUmakefile.preamble
|
||||
|
||||
# Include in the rules for making Objective-C programs
|
||||
include $(GNUSTEP_MAKEFILES)/objc.make
|
||||
|
||||
-include GNUmakefile.postamble
|
||||
@end example
|
||||
|
||||
|
||||
To compile a package that uses the Makefile Package, type @code{make} in the
|
||||
top-level directory of the package. A non-GNUstep Objective-C file may be
|
||||
compiled by adding @code{-lobjc on} at the command line.
|
||||
|
||||
|
||||
@subsection Debug and Profile Information
|
||||
|
||||
|
||||
By default the Makefile Package does not flag the compiler to generate debugging
|
||||
information that is generated by typing:
|
||||
|
||||
@code{make debug=yes}
|
||||
|
||||
This command also causes the Makefile Package to turn off optimization. It is
|
||||
therefore necessary to override the optimization flag when running Make if both
|
||||
debugging information and optimization is required. Use the variable OPTFLAG to
|
||||
override the optimization flag.
|
||||
|
||||
By default the Makefile Package does not instruct the compiler to create profiling
|
||||
information that is generated by typing:
|
||||
|
||||
@code{make profile=yes}
|
||||
@sp 1
|
||||
|
||||
@subsection Static, Shared and DLLs
|
||||
|
||||
By default the Makefile Package generates a shared library if it is building a
|
||||
library project type, and it will link with shared libraries if it is building
|
||||
an application or command-line tool project type. To tell the Makefile Package
|
||||
not to build using shared libraries but using static libraries instead, type:
|
||||
|
||||
@code{make shared=no}
|
||||
|
||||
This default is only applicable on systems that support shared libraries;
|
||||
systems that do not support shared libraries will always build using static
|
||||
libraries. Some systems support DLLs that are a form of shared libraries; on
|
||||
these systems DLLs are built by default unless the Makefile Package is told to
|
||||
build using static libraries instead.
|
||||
|
||||
@section Project Types
|
||||
|
||||
Projects are divided into different types. To create a project of a specific
|
||||
type, a make file is specified:
|
||||
|
||||
@code{include $(GNUSTEP_MAKEFILES)/application.make}
|
||||
|
||||
Each project type is independent, and if you want to create two project types in
|
||||
the same directory (e.g. a tool and a Java program), include both the desired
|
||||
make files in your main Make file.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Aggregate - aggregate.make
|
||||
|
||||
An Aggregate project holds several sub-projects that are of any valid
|
||||
project type (including the Aggregate type). The only project variable is the
|
||||
SUBPROJECTS variable:
|
||||
|
||||
@code{Aggregate project: SUBPROJECTS}
|
||||
|
||||
SUBPROJECTS defines the directory names that hold the sub-projects that the
|
||||
Aggregate project should build.
|
||||
|
||||
|
||||
@item Graphical Applications - application.make
|
||||
|
||||
An application is an Objective-C program that includes a GUI component, and by
|
||||
default links in all the GNUstep libraries required for GUI development, such as
|
||||
the Base and GUI libraries.
|
||||
|
||||
|
||||
@item Bundles - bundle.make
|
||||
|
||||
A bundle is a collection of resources and code that can be used to enhance an
|
||||
existing application or tool dynamically using the NSBundle class from the
|
||||
GNUstep base library.
|
||||
|
||||
|
||||
@item Command Line C Tools - ctool.make
|
||||
|
||||
A ctool is a project that uses only C language files. Otherwise it is similar to
|
||||
the ObjC project type.
|
||||
|
||||
|
||||
@item Documentation - documentation.make
|
||||
|
||||
The Documentation project provides rules to use various types of documentation
|
||||
such as texi and LaTeX documentation, and convert them into finished
|
||||
documentation like info, PostScript, HTML, etc.
|
||||
|
||||
@item Frameworks - framework.make
|
||||
|
||||
A Framework is a collection of resources and a library that provides common code
|
||||
that can be linked into a Tool or Application. In many respects it is similar to
|
||||
a Bundle.
|
||||
|
||||
@item Java - java.make
|
||||
|
||||
This project provides rules for building java programs. It also makes it easy to
|
||||
make java projects that interact with the GNUstep libraries.
|
||||
|
||||
@item Libraries - library.make
|
||||
|
||||
The Makefile Package provides a project type for building libraries that may be
|
||||
static, shared, or dynamic link libraries (DLLs). The latter two variants are
|
||||
supported only on some platforms.
|
||||
@end itemize
|
36
Documentation/manual/Glossary.texi
Normal file
36
Documentation/manual/Glossary.texi
Normal file
|
@ -0,0 +1,36 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Glossary
|
||||
@appendix Glossary
|
||||
@cindex glossary
|
||||
|
||||
@c /* Empty glossary (to be completed). */
|
||||
|
||||
|
||||
Object
|
||||
|
||||
|
||||
Class
|
||||
|
||||
|
||||
Inheritance
|
||||
|
||||
|
||||
Polymorphism
|
||||
|
||||
|
||||
Encapsulation
|
||||
|
||||
|
||||
Invoke
|
||||
|
||||
|
||||
Method
|
||||
|
||||
|
||||
Makefile
|
||||
|
||||
|
||||
|
||||
|
||||
|
199
Documentation/manual/Introduction.texi
Normal file
199
Documentation/manual/Introduction.texi
Normal file
|
@ -0,0 +1,199 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Introduction
|
||||
@chapter Introduction
|
||||
|
||||
The aim of this manual is to introduce you to the Objective-C language and the GNUstep development environment. The manual is organised to give you a tutorial introduction to the language, by using examples whenever possible, rather than providing a lengthy description of the language.
|
||||
|
||||
While Objective-C is not a difficult language to learn or use, some of the terms may be unfamiliar, especially to those that have not programmed using an object-oriented programming language before. Whenever possible, concepts will be explained in simple terms rather than in more advanced programming terms. So to start I'll give you a brief description of object-oriented programming, the Objective-C language and the GNUstep development environment.
|
||||
|
||||
The descriptions are not authoritative, and given only as a grounding for the topics that follow.
|
||||
|
||||
@section What is Object-Oriented Programming?
|
||||
@cindex object-oriented programming
|
||||
|
||||
There are several object-oriented (OO) programming languages in common use today and you have probably heard of some of them: C++ and Java for example, and of course Objective-C. OO languages all have one thing in common: they allow you to design and write programs in a different way than if you used a traditional procedural language like C or Pascal.
|
||||
|
||||
Procedural languages provide the programmer with basic building blocks that consist of data types, (integers, characters, float etc) and functions that act on that data. This forces the program designer to design the program using these same building blocks. Quite often this requires quite a leap in imagination between what the program must do and how it can be implemented.
|
||||
|
||||
Object-oriented languages allow the program designer to think in terms of building blocks that are closer to what the program will actually do. Rather than think in terms of data and functions that act on that data, OO languages provide you with objects and the ability to send messages to those objects. Objects are, in a sense, like mini programs that can function on their own when requested by the program or even another object.
|
||||
|
||||
For example, an object may exist that can draw a rectangle in a window; all you need to do as a programmer is send the appropriate messages to that object. The messages could tell the object the size of the rectangle and position in the window, and of course tell the object to draw itself. Program design and implementation is now reduced to sending messages to the appropriate objects rather than calling functions to manipulate data.
|
||||
|
||||
@subsection Some Basic OO Terminology
|
||||
@cindex basic OO terminology
|
||||
|
||||
OO languages add to the vocabulary of more traditional programming languages, and it may help if you become familiar with some of the basic terms before jumping in to the language itself.
|
||||
|
||||
Objects
|
||||
|
||||
As stated previously, an object is one of the basic building blocks in OO programming. An object can receive messages and then act on these messages to alter the state of itself (the size and position of a rectangle object for example). In software an object consists of instance variables (data) that represent the state of the object, and methods (like C functions) that act on these variables in response to messages.
|
||||
|
||||
Rather than 'calling' one of its methods, an object is said to 'perform' one of its methods in response to a message. (A method is known as a 'member function' in C++.)
|
||||
|
||||
Classes
|
||||
|
||||
All objects of the same type are said to be members of the same class. To continue with the rectangle example, every rectangle could belong to a rectangle class, where the class defines the instance variables and the methods of all rectangles.
|
||||
|
||||
A class definition by itself does not create an object but instead acts like a template for each object in that class. When an object is created an 'instance' of that class is said to exist. An instance of a class (an object) has the same data structure (instance variables) and methods as every other object in that class.
|
||||
|
||||
Inheritance
|
||||
|
||||
When you define a new class you can base it on an existing class. The new class would then 'inherit' the data structure and methods of the class that you based it on. You are then free to add instance variables and methods, or even modify inherited methods, to change the behavior of the new class (how it reacts to messages).
|
||||
|
||||
The base class is known as the 'superclass' and the new class as the 'subclass' of this superclass. As an example, there could be a superclass called 'shapes' with a data structure and methods to size, position and draw itself, on which you could base the rectangle class.
|
||||
|
||||
Polymorphism
|
||||
|
||||
Unlike functions in a procedural program such as C, where every function must have a unique name, a method (or instance variable) in one class can have the same name as that in another class.
|
||||
|
||||
This means that two objects could respond to the same message in completely different ways, since identically named methods may do completely different things. A draw message sent to a rectangle object would not produce the same shape as a draw message sent to a circle object.
|
||||
|
||||
Encapsulation
|
||||
|
||||
An object hides its instance variables and method implementations from other parts of the program. This encapsulation allows the programmer that uses an object to concentrate on what the object does rather than how it is implemented.
|
||||
|
||||
Also, providing the interface to an object does not change (the methods of an object and how they respond to received messages) then the implementation of an object can be improved without affecting any programs that use it.
|
||||
|
||||
Dynamic Typing and Binding
|
||||
|
||||
Due to polymorhism, the method performed in response to a message depends on the class (type) of the receiving object. In an OO program the type, or class, of an object can be determined at run time (dynamic typing) rather than at compile time (static typing).
|
||||
|
||||
The method performed (what happens as a result of this message) can then be determined during program execution and could, for example, be determined by user action or some other external event. Binding a message to a particular method at run time is known as dynamic binding.
|
||||
|
||||
@section What is Objective-C?
|
||||
@cindex what is Objective-C?
|
||||
@cindex Objective-C, what is?
|
||||
|
||||
Objective-C is a powerful object-oriented (OO) language that extends the procedural language ANSI C with the addition of a few keywords and compiler directives, plus one syntactical addition (for sending messages to objects). This simple extension of ANSI C is made possible by an Objective-C runtime library (libobjc) that is generally transparent to the Objective-C programmer.
|
||||
|
||||
During compilation of Objective-C source code, OO extensions in the language compile to C function calls to the runtime library. It is the runtime library that makes dynamic typing and binding possible, and that makes Objective-C a true object-oriented language.
|
||||
|
||||
Since Objective-C extends ANSI C with a few additional language constructs (the compiler directives and syntactical addition), you may freely include C code in your Objective-C programs. In fact an Objective-C program may look familiar to the C programmer since it is constructed using the traditional @code{main} function.
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <objc/objc.h>
|
||||
|
||||
int main (void)
|
||||
@{
|
||||
|
||||
/* Objective C and C code */
|
||||
|
||||
return(0);
|
||||
@}
|
||||
@end example
|
||||
|
||||
Objective-C source files are compiled using the standard GNU @b{gcc} compiler. The compiler recognises Objective-C source files by the .m file extension, C files by the .c extension and header files by the .h extension.
|
||||
|
||||
As an example, the command @b{$gcc -o testfile testfile.m -lobjc} would compile the Objective-C source file @code{testfile.m} to an executable named @code{testfile}. The @code{-lobjc} compiler option is required for linking an Objective-C program to the runtime library.
|
||||
|
||||
The GNUstep @b{make} utility provides an alternative (and simple) way to compile large projects, and this useful utility is discussed in the next section.
|
||||
|
||||
@section What is GNUstep?
|
||||
@cindex what is GNUstep?
|
||||
@cindex GNUstep, what is?
|
||||
|
||||
GNUstep is an object-oriented development environment that provides the Objective-C programmer with a range of utilities and libraries for building large, cross-platform, applications and tools.
|
||||
|
||||
This manual does not discuss the full functionality of GNUstep but concentrates on using the GNUstep base library to create non-graphical programs, and the GNUstep @b{make} utility to compile these programs. Further information about GNUstep can be found at @url{http://www.gnustep.org}.
|
||||
|
||||
@subsection GNUstep Base Library
|
||||
@cindex GNUstep base library
|
||||
|
||||
The GNUstep base library contains a powerful set of non-graphical Objective-C classes that can readily be used in your programs. At present there are approximately 70 different classes available, including classes to handle strings and arrays, dates and times, distributed objects, URLs and file systems (to name but a few).
|
||||
|
||||
Classes in the base library are easily identified since they begin with the upper case characters 'NS', as in @code{NSString}. Some examples in this manual use classes from the base library, but for complete documentation on the base library visit the GNUstep web site at @url{http://www.gnustep.org}.
|
||||
|
||||
@subsection GNUstep Make Utility
|
||||
@cindex GNUstep make utility
|
||||
|
||||
The GNUstep @b{make} utility is the GNU version of the UNIX make utility. So what does it do? It simplifies the process of building (compiling and linking) a large project. You simply type @b{make} at the command prompt and the make utility takes care of file dependencies, only re-compiling source files that have changed, or that depend on files that have changed, since the last 'make' (a header file for example).
|
||||
|
||||
Before using @b{make} you must first create a 'makefile' that lists all the files and file dependencies in your project. The easiest way to do this is to copy an existing makefile and change it to suit your own project.
|
||||
|
||||
The make utility will be used to build the Objective-C examples shown in this manual, and when an example can be compiled then the makefile will also be shown. Further information about makefiles and the make utility can be found in Appendix C.
|
||||
|
||||
@section Building Your First Objective-C Program
|
||||
@cindex your first Objective-C program
|
||||
|
||||
The following example will show you how to create and compile an Objective-C program. The example simply displays a text message on the screen, and there are easier ways to to do this, but the example does demonstrate a number of object-oriented features of Objective-C, and also demonstrates the use of @b{make} to compile an Objective-C program.
|
||||
|
||||
@enumerate
|
||||
|
||||
@item
|
||||
Create a new project directory to hold your project.@*@*
|
||||
|
||||
@item
|
||||
Create the following Objective-C source code using your favourite text
|
||||
editor and save it in the project directory with the filename @code{source.m}.
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* The next #include line is generally present in all Objective-C
|
||||
* source files that use GNUstep. The Foundation.h header file
|
||||
* includes all the other standard header files you need.
|
||||
*/
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
/*
|
||||
* Declare the Test class that implements the class method (classStringValue).
|
||||
*/
|
||||
@@interface Test
|
||||
+ (const char *) classStringValue;
|
||||
@@end
|
||||
|
||||
/*
|
||||
* Define the Test class and the class method (classStringValue).
|
||||
*/
|
||||
@@implementation Test
|
||||
+ (const char *) classStringValue;
|
||||
@{
|
||||
return "This is the string value of the Test class";
|
||||
@}
|
||||
@@end
|
||||
|
||||
/*
|
||||
* The main() function: pass a message to the Test class
|
||||
* and print the returned string.
|
||||
*/
|
||||
int main(void)
|
||||
@{
|
||||
printf("%s\n", [Test classStringValue]);
|
||||
return 0;
|
||||
@}
|
||||
@end example
|
||||
|
||||
The text between comment markers (/* */) is ignored by the compiler but indicates to someone reading the source file what each part of the program does. The program is an example of a (class) method responding to a message. Can you see how it works?@*@*
|
||||
|
||||
A message is sent to the @code{Test} class as an argument to @code{printf()}, requesting the string value of that class. The @code{Test} class performs its @code{classStringValue} method in response to this message and returns a string that is finally printed. No object is created in this program since a class method does not require an instance of a class in order to respond to a message.@*@*
|
||||
|
||||
You will learn more about class methods in the next chapter.@*@*
|
||||
|
||||
@item
|
||||
Now create the makefile, again using your favourite text editor, and save it in the same project directory with the filename @code{GNUmakefile}.
|
||||
|
||||
@example
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
TOOL_NAME = LogTest
|
||||
LogTest_OBJC_FILES = source.m
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/tool.make
|
||||
@end example
|
||||
|
||||
If you look at the makefile above you will notice the two lines that tell the make utility to build a tool with the filename @code{LogTest} from the Objective-C source file @code{source.m}. You could copy and modify this makefile for later projects you may have: just change the tool name and list the new source files.@*@*
|
||||
|
||||
The two 'include' lines are just a way of keeping your makefile simple, by including two 'ready-made' makefiles that someone else created.@*@*
|
||||
|
||||
@item
|
||||
You can now compile the project using make. At the system command prompt, change to the project directory and enter the @b{make} command.@*@*
|
||||
|
||||
@item
|
||||
Run the program (for Linux enter @b{./LogTest} at the command prompt). The message "This is the string value of the Test class" will be displayed (assuming there were no errors).
|
||||
|
||||
@end enumerate
|
||||
|
||||
You have now compiled and run you first Objective-C program. Hungry for more? Then read on.
|
8
Documentation/manual/JavaAndGuile.texi
Normal file
8
Documentation/manual/JavaAndGuile.texi
Normal file
|
@ -0,0 +1,8 @@
|
|||
@node Java and Guile
|
||||
@appendix Programming GNUstep in Java and Guile
|
||||
@cindex Java and Guile, programming GNUstep
|
||||
|
||||
Other appendices might explain how to use GNUstep from Java and from
|
||||
guile, with examples but without becoming a full reference about it.
|
||||
For that, more complete documentation should be/is bundled with the
|
||||
interfaces.
|
218
Documentation/manual/ObjcAndJava.texi
Normal file
218
Documentation/manual/ObjcAndJava.texi
Normal file
|
@ -0,0 +1,218 @@
|
|||
@node Obj-C and Java
|
||||
@appendix Differences and Similarities Between Objective-C and Java
|
||||
@cindex Objective-C and Java, differences and similarities
|
||||
@cindex differences and similarities, Objective-C and Java
|
||||
|
||||
@paragraphindent 0
|
||||
|
||||
This appendix explains the differences/similarities between Objective-C
|
||||
and Java. It has nothing to do with JIGS, but is included to help people who want to learn Objective-C and know Java
|
||||
already.
|
||||
|
||||
@section General
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
C programmers may learn Objective-C in hours (though real expertise
|
||||
obviously takes much longer).
|
||||
|
||||
@item
|
||||
Java has global market acceptance.
|
||||
|
||||
@item
|
||||
Objective-C is a compiled OO programming language.
|
||||
|
||||
@item
|
||||
Java is both compiled and interpreted and therefore does not offer
|
||||
the same run-time performance as Objective-C.
|
||||
|
||||
@item
|
||||
Objective-C features efficient, transparent Distributed Objects.
|
||||
|
||||
@item
|
||||
Java features a less efficient and less transparent Remote Machine
|
||||
Interface.
|
||||
|
||||
@item
|
||||
Objective-C has basic CORBA compatibility through official C bindings,
|
||||
and full compatibility through unofficial Objective-C bindings.
|
||||
|
||||
@item
|
||||
Java has CORBA compatibility through official Java bindings.
|
||||
|
||||
@item
|
||||
Objective-C is portable across heterogeneous networks by virtue of a
|
||||
near omnipresent compiler (gcc).
|
||||
|
||||
@item
|
||||
Java is portable across heterogeneous networks by using client-side JVMs
|
||||
that are software processors or runtime environments.
|
||||
|
||||
|
||||
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Language
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Objective-C is a superset of the C programming language, and may
|
||||
be used to develop non-OO and OO programs. Objective-C provides
|
||||
access to scalar types, structures and to unions, whereas Java
|
||||
only addresses a small number of scalar types and everything else
|
||||
is an object. Objective-C provides zero-cost access to existing
|
||||
software libraries written in C, Java requires interfaces to be
|
||||
written and incurs runtime overheads.
|
||||
|
||||
@item
|
||||
Objective-C is dynamically typed but also provides static typing.
|
||||
Java is statically types, but provides type-casting mechanisms to
|
||||
work around some of the limitations of static typing.
|
||||
|
||||
@item
|
||||
Java tools support a convention of a universal and distributed
|
||||
name-space for classes, where classes may be downloaded from
|
||||
remote systems to clients. Objective-C has no such conventions
|
||||
or tool support in place.
|
||||
|
||||
@item
|
||||
Using Java, class definitions may not be divided or extended through
|
||||
the addition of logical groupings. Objective-C's provides categories
|
||||
as a solution to this problem.
|
||||
|
||||
@item
|
||||
Objective-C provides delegation (the benefits of multiple inheritance
|
||||
without the drawbacks) at minimal programming cost. Java requires
|
||||
purpose written methods for any delegation implemented.
|
||||
|
||||
@item
|
||||
Java provides garbage collection for memory management. Objective-C
|
||||
provides manual memory management, reference counting, and garbage
|
||||
collection.
|
||||
|
||||
@item
|
||||
Java provides interfaces, Objective-C provides protocols.
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Source Differences
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Objective-C is based on C, and the OO extensions are comparable with
|
||||
those of Smalltalk. The Java syntax is based on the C++ programming
|
||||
language.
|
||||
|
||||
@item
|
||||
The object (and runtime) models are comparable, with Java's
|
||||
implementation having a subset of the functionality of that
|
||||
of Objective-C.
|
||||
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Compiler Differences
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Objective-C compilation is specific to the target system/environment,
|
||||
and because it is an authentic compiled language it runs at higher
|
||||
speeds than Java.
|
||||
|
||||
@item
|
||||
Java is compiled into a byte stream or Java tokens that are interpreted
|
||||
by the target system, though fully compiled Java is possible.
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Developer's Workbench
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Objective-C is supported by tools such as GNUstep that provides
|
||||
GUI development, compilation, testing features,
|
||||
debugging capabilities, project management and database access.
|
||||
It also has numerous tools for developing projects of different
|
||||
types including documentation.
|
||||
|
||||
@item
|
||||
Java is supported by numerous integrated development environments
|
||||
(IDEs) that often have their origins in C++ tools.
|
||||
Java has a documentation tool that parses source code and creates
|
||||
documentation based on program comments. There are similar features
|
||||
for Objective-C.
|
||||
|
||||
@item
|
||||
Java is more widely used.
|
||||
|
||||
@item
|
||||
Objective-C may leverage investment already made in C based tools.
|
||||
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Longevity
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Objective-C has been used for over ten years, and is considered to be
|
||||
in a stable and proven state, with minor enhancements from time to time.
|
||||
|
||||
@item
|
||||
Java is evolving constantly.
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Databases
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Apple's EOF tools enable Objective-C developers to build object
|
||||
models from existing relational database tables. Changes in the
|
||||
database are automatically recognised, and there is no requirement
|
||||
for SQL development.
|
||||
|
||||
@item
|
||||
Java uses JDBC that requires SQL development; database changes
|
||||
affect the Java code. This is considered inferior to EOF.
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Memory
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
For object allocation Java has a fixed heap whose maximum size
|
||||
is set when the JVM starts and cannot be resized unless the
|
||||
JVM is restarted. This is considered to be a disadvantage in
|
||||
certain scenarios: for example, data read from databases may
|
||||
cause the JVM to run out of memory and to crash.
|
||||
|
||||
@item
|
||||
Objective-C's heap is managed by the OS and the runtime system.
|
||||
This can typically grow to consume all system memory (unless
|
||||
per-process limits have been registered with the OS).
|
||||
|
||||
|
||||
@end itemize
|
||||
|
||||
@section Design Stability
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Objective-C: A consistent API is provided by the OpenStep software
|
||||
libraries. Mainstream developers may require knowledge of four to
|
||||
five APIs, all of which have consistent style/conventions.
|
||||
|
||||
@item
|
||||
Java package APIs are numerous and may use different styles.
|
||||
|
||||
@end itemize
|
||||
|
609
Documentation/manual/ObjcLanguage.texi
Normal file
609
Documentation/manual/ObjcLanguage.texi
Normal file
|
@ -0,0 +1,609 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Objective-C
|
||||
@chapter The Objective-C Language
|
||||
|
||||
In the previous chapter you were introduced to some basic object-oriented programming terms. This chapter will expand on these terms, and introduce you to some new ones, while concentrating on how they apply to the Objective-C language and the GNUstep base library. First let us look at some non OO additions that Objective-C makes to ANSI C.
|
||||
|
||||
@section Non OO Additions
|
||||
|
||||
Objective-C makes a few non OO additions to the syntax of the C programming
|
||||
language that include:
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
A boolean data type (@code{BOOL}) capable of storing either of the
|
||||
values @code{YES} or @code{NO}.@*
|
||||
A @code{BOOL} is a scalar value and can be used like the familiar
|
||||
@code{int} and @code{char} data types.@*
|
||||
A @code{BOOL} value of @code{NO} is zero, while @code{YES} is non-zero.
|
||||
|
||||
@item
|
||||
The use of a pair of slashes (@code{//}) to mark text up to the end
|
||||
of the line as a comment.
|
||||
|
||||
@item
|
||||
The @code{#import} preprocessor directive was added, but its use is deprecated (it still works but it should not be used for new programs).
|
||||
@end itemize
|
||||
|
||||
|
||||
@section Objects
|
||||
@cindex objects
|
||||
@c objects
|
||||
|
||||
Object-oriented (OO) programming is based on the notion that a software system can be composed of objects that interact with each other in a manner that parallels the interaction of objects in the physical world.
|
||||
|
||||
This model makes it easier for the programmer to understand how software works since it makes programming more intuitive. The use of objects also makes it easier during program design: take a big problem and consider it in small pieces, the individual objects, and how they relate to each other.
|
||||
|
||||
Objects are like mini programs that can function on their own when requested by the program or even another object. An object can receive messages and then act on these messages to alter the state of itself (the size and position of a rectangle object in a drawing program for example).
|
||||
|
||||
In software an object consists of instance variables (data) that represent the state of the object, and methods (like C functions) that act on these variables in response to messages.
|
||||
|
||||
As a programmer creating an application or tool, all you need do is send messages to the appropriate objects rather than call functions that manipulate data as you would with a procedural program.
|
||||
|
||||
The syntax for sending a message to an object, as shown below, is one of the additions that Objective-C adds to ANSI C.
|
||||
|
||||
@example
|
||||
[objectName message];
|
||||
@end example
|
||||
|
||||
Note the use of the square [ ] brackets surrounding the name of the object and message.
|
||||
|
||||
Rather than 'calling' one of its methods, an object is said to 'perform' one of its methods in response to a message. The format that a message can take is discussed later in this section.
|
||||
|
||||
@subsection Id and nil
|
||||
|
||||
Objective-C defines a new type to identify an object: @code{id}, a type that points to an object's data (its instance variables). The following code declares the variable 'button' as an object (as opposed to 'button' being declared an integer, character or some other data type).
|
||||
@example
|
||||
id button;
|
||||
@end example
|
||||
|
||||
When the button object is eventually created the variable name 'button' will point to the object's data, but before it is created the variable could be assigned the numeric value 0, to indicate to other code that the object does not yet exist.
|
||||
|
||||
Objective-C defines a new keyword @code{nil} for this assignment, where @code{nil} is of type @code{id} with the numeric value 0. In the button example, the assignment could look like this:
|
||||
|
||||
@example
|
||||
id button = nil;
|
||||
@end example
|
||||
|
||||
which assigns @code{nil} in the declaration of the variable.
|
||||
|
||||
You can then test the value of an object to determine whether the object exists, perhaps before sending the object a message. If the test fails, then the object does not exist and your code can execute an alternative statement.
|
||||
@example
|
||||
if (anObject != nil)
|
||||
... /* send message */
|
||||
else ... /* do something else */
|
||||
@end example
|
||||
|
||||
The header file @code{objc/objc.h} defines @code{id}, @code{nil}, and other basic types of the Objective-C language. It can be included in your source code with the compiler directive @code{#include <Foundation/Foundation.h>}.
|
||||
|
||||
@subsection Messages
|
||||
@cindex messages
|
||||
|
||||
A message in Objective-C is the mechanism by which you pass instructions
|
||||
to objects. You may tell the object to do something for you, tell it to
|
||||
change its internal state, or ask it for information.
|
||||
|
||||
A message usually invokes a method, causing the receiving object
|
||||
to respond in some way.
|
||||
Objects and data are manipulated by sending messages to them.
|
||||
Like C-functions they have return types, but function specific to the object.
|
||||
|
||||
Objects respond to messages that make specific requests.
|
||||
Message expressions are enclosed in square brackets and include the
|
||||
receiver or object name and the message or method name along with
|
||||
any arguments.
|
||||
|
||||
To send a message to an object, use the syntax:
|
||||
|
||||
@code{[receiver messagename];}
|
||||
|
||||
where @code{receiver} is the object.
|
||||
@sp 1
|
||||
|
||||
The run-time system invokes object methods that are specified by messages.
|
||||
For example, to invoke the display method of the mySquare object the
|
||||
following message is used:
|
||||
|
||||
@code{[mySquare display];}
|
||||
@sp 1
|
||||
Messages may include arguments that are prefixed by colons, in which
|
||||
case the colons are part of the message name, so the following message
|
||||
is used to invoke the @code{setFrameOrigin::} method:
|
||||
|
||||
@code{[button setFrameOrigin: 10.0 : 10.0];}
|
||||
@sp 1
|
||||
|
||||
Labels describing arguments precede colons:
|
||||
|
||||
@code{[button setWidth: 20.0 height: 122.0];}
|
||||
invokes the method named @code{setWidth:height:}
|
||||
@sp 1
|
||||
Messages that take a variable number of arguments are of the form:
|
||||
|
||||
@code{[receiver makeList: list, argOne, argTwo, argThree];}
|
||||
@sp 1
|
||||
|
||||
A message to nil does NOT crash the application (while in Java messages
|
||||
to null raise exceptions); the Objective-C application does nothing.
|
||||
|
||||
For example:
|
||||
|
||||
@code{[nil display];}
|
||||
|
||||
will do nothing.
|
||||
|
||||
If a message to nil is supposed to return an object, it will return nil.
|
||||
But if the method is supposed to return something else, then the
|
||||
return value of that method when invoked on nil, is undefined.
|
||||
The programmer therefore
|
||||
needs to avoid using the return value in this instance.
|
||||
|
||||
|
||||
@subsection Polymorphism
|
||||
@cindex polymorphism
|
||||
|
||||
Polymorphism refers to the fact that two different objects may
|
||||
respond differently to the same message. For example when client
|
||||
objects receive an alike message from a server object, they may
|
||||
respond differently. Using Dynamic Binding, the run-time system
|
||||
determines which code to execute according to the object type.
|
||||
|
||||
|
||||
@section Classes
|
||||
@cindex classes
|
||||
@emph{needs to be clearer/readable and say what a class is? also explain
|
||||
instances!}@*
|
||||
Objects form groups or classes, and those in the same class hold
|
||||
the same type of data, and may execute the same methods.
|
||||
Objects are defined by their originating classes.
|
||||
Each class compilation sees the creation of a factory or class object
|
||||
that builds instances of the class. Instances and Objects are synonymous,
|
||||
and are the components that are operating entities in the running program.
|
||||
|
||||
|
||||
@subsection Inheritance
|
||||
@cindex inheritance
|
||||
|
||||
Most of the programmer's time is spent defining classes.
|
||||
Inheritance helps reduce coding time by providing a convenient way of
|
||||
reusing code.
|
||||
For example, the NSButton class defines data (or instance variables) and methods to create button objects of a certain type, so a subclass of NSButton could be produced to create buttons of another type - which may perhaps have a different border colour. Equally NSTextField can be used to define a subclass that perhaps draws a different border, by reusing definitions and data in the superclass.
|
||||
|
||||
Inheritance places all classes in a logical hierarchy or tree
|
||||
structure that may have the NSObject class at its root.
|
||||
All classes may have subclasses, and all except the root class
|
||||
may have superclasses. When a class object creates a new instance,
|
||||
the new object holds the data for its class, superclass,
|
||||
and superclasses extending to the root class (typically NSObject).
|
||||
Additional data may be added to classes so as to provide
|
||||
specific functions and application logic.
|
||||
|
||||
When a new object is created, it is allocated memory space,
|
||||
and its data in the form of its instance variables are initialised.
|
||||
The object holds the @code{isa} variable refers to the object's class,
|
||||
and this also provides access to classes in the object's inheritance
|
||||
path.
|
||||
|
||||
An Objective-C class has an:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
interface declaring instance variables, methods and the superclass name.
|
||||
|
||||
@item
|
||||
implementation that defines the class in terms of operational code that
|
||||
implements the methods.
|
||||
@end itemize
|
||||
|
||||
Typically these entities are confined to separate files
|
||||
with .h and .m extensions for Interface and Implementation files,
|
||||
respectively. However they may be merged
|
||||
into one file, and a single file may implement multiple classes.
|
||||
|
||||
@subsection Inheritance of Methods
|
||||
@cindex inheriting methods
|
||||
|
||||
Each new class inherits methods and instance variables from another class. This
|
||||
results in a class hierarchy with the root class at the core, and every class
|
||||
(except the root) has a superclass as its parent, and all classes may have
|
||||
numerous subclasses as their children. Each class therefore is a refinement of
|
||||
its superclass(es).
|
||||
|
||||
|
||||
@subsection Overriding Methods
|
||||
@cindex overriding methods
|
||||
|
||||
Objects may access methods defined for their class, superclass,
|
||||
superclass' superclass, extending to the root class.
|
||||
Classes may be defined with methods that overwrite their namesakes
|
||||
in ancestor classes. These new methods are then inherited by
|
||||
subclasses, but other methods in the new class can locate the
|
||||
overridden methods. Additionally redefined methods may include
|
||||
overridden methods.
|
||||
|
||||
|
||||
@subsection Abstract Classes
|
||||
@cindex abstract class
|
||||
@cindex class, abstract
|
||||
|
||||
Abstract classes or abstract superclasses such as NSObject define
|
||||
methods and instance variables used by multiple subclasses.
|
||||
Their purpose is to reduce the development effort required to
|
||||
create subclasses and application structures.
|
||||
When we get technical, we make a distinction between a pure abstract
|
||||
class whose methods are defined but instance variables are not,
|
||||
and a semi-abstract class where instance variables are defined).
|
||||
An abstract class is not expected to actually produce functional
|
||||
instances since crucial parts of the code are expected to be
|
||||
provided by subclasses.
|
||||
Abstract classes reduce the development effort required to create
|
||||
subclasses and application structures.
|
||||
|
||||
|
||||
@subsection Class Clusters
|
||||
@cindex class cluster
|
||||
@cindex cluster, classes
|
||||
|
||||
A class cluster is an abstract base class, and a group of private, concrete
|
||||
subclasses. It is used to hide implementation details from the programmer
|
||||
(who is only allowed to use the interface provided by the abstract class),
|
||||
so that the actual design can be modified (probably optimised) at a later
|
||||
date, without breaking any code that uses the cluster.
|
||||
Consider a scenario where it is necessary to create a class hierarchy
|
||||
to define objects holding different types including @b{chars}, @b{ints},
|
||||
@b{short}, @b{LongInt}, @b{floats} and @b{doubles}.
|
||||
Of course, different types could be defined in the same class
|
||||
since it is possible to @b{cast} or @b{change} them from one to the next.
|
||||
Their allocated storage differs, however, so it would be inefficient
|
||||
to bundle them in the same class and to convert them in this way.
|
||||
|
||||
The solution to this problem is to use a class cluster:
|
||||
define an abstract superclass that specifies and declares
|
||||
components for subclasses, but does not declare instance variables.
|
||||
Rather this declaration is left to its subclasses, which share the
|
||||
@b{programmatic interface} that is declared by the abstract superclass.
|
||||
|
||||
When you create an object using a cluster interface, you are
|
||||
given an object of another class - from a concrete class in the cluster.
|
||||
|
||||
@section Using the GNUstep Base Library
|
||||
@cindex GNUstep base library, class documentation
|
||||
@cindex class documentation for the base library
|
||||
|
||||
***
|
||||
Add something here about using the base library. Some suggestions:
|
||||
|
||||
Explain class documentation, what it is (documented class interface that programmers can use), how to use it (the need to read it and comply with the interface methods and arguments), and how to get it (www.gnustep.org).
|
||||
|
||||
Also explain some of the terminology, like 'returns a copy of the receiving object'.
|
||||
***
|
||||
|
||||
@section NSObject: The Root Class
|
||||
@cindex NSObject
|
||||
@cindex root class
|
||||
@cindex class, root
|
||||
|
||||
NSObject is a root class that provides the framework for all objects,
|
||||
their interactions, and their integration in the run-time system.
|
||||
NSObject defines the @code{isa} instance variable that connects
|
||||
every object with its class
|
||||
NSObject or an alternative root class:
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
allocates instances
|
||||
|
||||
@item
|
||||
connects instances to their class
|
||||
|
||||
@item
|
||||
forces the run-time system to discover instances involuntarily.
|
||||
@end itemize
|
||||
|
||||
The NSObject interface is defined as the methods declared by itself, and
|
||||
those defined by the NSObject protocol. This division ensures that objects
|
||||
inheriting from other root classes can act as ordinary objects that do not
|
||||
inherit from NSObject. NSObject provides the facilities for inheriting
|
||||
classes whose instances are given a behaviour that includes the
|
||||
ability to:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
create objects.
|
||||
|
||||
@item
|
||||
initialize objects.
|
||||
|
||||
@item
|
||||
deallocate objects.
|
||||
|
||||
@item
|
||||
compare objects.
|
||||
|
||||
@item
|
||||
archive objects.
|
||||
|
||||
@item
|
||||
perform methods selected at run-time.
|
||||
|
||||
@item
|
||||
query objects about their methods.
|
||||
|
||||
@item
|
||||
query objects about their position in the inheritance hierarchy.
|
||||
|
||||
@item
|
||||
forward messages to other objects (See Section respondsToSelector).
|
||||
@end itemize
|
||||
|
||||
@subsection Initializing Objects
|
||||
All objects inherit from the NSObject class, and their initialization requires:
|
||||
@itemize @bullet
|
||||
@item
|
||||
an @code{isa} instance variable that points to a class structure.
|
||||
@item
|
||||
initialization of @code{isa} is performed by @code{alloc} and
|
||||
@code{allocWithZone:} methods that are also used to create
|
||||
(allocate memory for) new instances of classes.
|
||||
@end itemize
|
||||
|
||||
|
||||
@section Static Typing
|
||||
|
||||
Type checking is good programming practice because it catches errors;
|
||||
it checks code, but does not change compiled code.
|
||||
|
||||
|
||||
When declaring an object type, static typing permits a class name to
|
||||
be used instead of an @code{id}. In the
|
||||
following example Type Checking verifies that the myString object
|
||||
is an appropriate type.
|
||||
|
||||
@example
|
||||
NSString *myString = anObject;
|
||||
@end example
|
||||
|
||||
Objects can be statically typed as pointers to a class,
|
||||
by making the pointer explicit (as opposed to hidden using @code{id}).
|
||||
Static typing permits the compiler to run some obvious checks,
|
||||
forewarning of such errors as message incompatibilities.
|
||||
A subclass can be used where a superclass is expected, but not vice-versa.
|
||||
|
||||
Formal protocols may be included in type definitions, giving another tier of
|
||||
type checking to the compiler. Protocol names are included between angle
|
||||
brackets:
|
||||
|
||||
@example
|
||||
|
||||
- (id <Formatting>) formattingService;
|
||||
id <ReferenceCounting,AutoFreeing> specificObject;
|
||||
|
||||
@end example
|
||||
|
||||
Formal protocols may declare a list of methods that are visible at source and
|
||||
run-time levels, so objects may introspect themselves at runtime to verify that
|
||||
they conform to protocols, and the compiler may check for types:
|
||||
|
||||
@example
|
||||
|
||||
@@protocol ProtocolTitle
|
||||
declare methods
|
||||
@@end
|
||||
|
||||
@end example
|
||||
|
||||
@subsection Type Introspection
|
||||
|
||||
Before sending a message you should check that the receiver is the
|
||||
correct class or has the appropriate method.
|
||||
The @code{isMemberOfClass:} method defined in the NSObject class
|
||||
verifies that the receiver is of a specific class:
|
||||
|
||||
@example
|
||||
if ([namedObject isMemberOfClass: specificClass] == YES)
|
||||
@{
|
||||
// code here
|
||||
@}
|
||||
@end example
|
||||
|
||||
The @code{isKindOfClass:} method checks to see if the receiver is
|
||||
in a specific inheritance path:
|
||||
|
||||
@example
|
||||
if ([namedObject isKindOfClass: specificClass] == YES)
|
||||
@{
|
||||
// code here
|
||||
@}
|
||||
@end example
|
||||
|
||||
|
||||
@section Working with Class Objects
|
||||
|
||||
|
||||
The compiler creates a class or factory object that instantiates objects
|
||||
or instances based on the class definitions; class objects are agents
|
||||
able to instantiate instances in the run-time system. A class object is
|
||||
not an instance and is without instance variables, though it does holds
|
||||
static variables and the class instance's prototype also; but it cannot
|
||||
implement methods for instances of the class.
|
||||
|
||||
A class definition may include class methods that are defined for the
|
||||
class object.
|
||||
A class object inherits class methods from superclasses,
|
||||
while instances inherit instance methods. Class objects may receive messages,
|
||||
and inherit methods from superclasses, but are without instance variables
|
||||
except those created using the class definition.
|
||||
|
||||
|
||||
@subsection Referring to Class Objects
|
||||
|
||||
To return the class version number of the @code{NSString} class
|
||||
using a method inherited from the NSObject class:
|
||||
|
||||
@code{int versionNumber = [NSString version];}
|
||||
|
||||
The class name @code{NSString} is that of the class object, which is the receiver
|
||||
in the above message expression. When not dealing with class objects,
|
||||
instances and classes are used to obtain the class @code{id}:
|
||||
|
||||
@example
|
||||
id stringClass = [stringObject class];
|
||||
id mStringClass = [NSMutableString class];
|
||||
@end example
|
||||
|
||||
Class objects may be typed @code{id}, and specifically typed to the Class:
|
||||
|
||||
@example
|
||||
Class stringClass = [stringObject class];
|
||||
Class mStringClass = [NSMutableString class];
|
||||
@end example
|
||||
|
||||
Class objects are of the type Class, rather like the class name is
|
||||
used to statically type instances.
|
||||
|
||||
@subsection Creating Instances
|
||||
|
||||
Class objects create new instances; to use the NSDate class to create
|
||||
a new @code{NSDate} instance and assign it to the @code{date} variable:
|
||||
|
||||
@example
|
||||
id date;
|
||||
date = [NSDate alloc];
|
||||
@end example
|
||||
|
||||
The alloc method equates the object's instance variables to zero
|
||||
with the exception of the @code{isa} variable, and also allocates
|
||||
memory for them. Complete initialisation of the object however
|
||||
relies on the @code{init} method that primes 'date' to receive messages:
|
||||
|
||||
@code{date = [[NSDate alloc] init];}
|
||||
|
||||
The alloc method returns a new instance that implements the
|
||||
@code{init} method, and like all instances and class objects
|
||||
it holds at least one method. The @code{init} method may take
|
||||
arguments so as to pass values.
|
||||
|
||||
@subsection Factory Patterns
|
||||
@emph{Nicola to complete}@*
|
||||
(To be completed.)
|
||||
|
||||
|
||||
|
||||
@subsection Factory or Class Objects
|
||||
Each class compilation sees the creation of a @b{factory object}
|
||||
or @b{class object} that builds class-specific objects. Objects
|
||||
instantiated by the factory object at run-time are @b{instances}
|
||||
of the class. Class names begin with an uppercase letter, while
|
||||
instance names begin with lowercase letter.
|
||||
|
||||
The compiler may create as many class objects as there are defined classes.
|
||||
The class objects are conventional objects that may be dynamically typed,
|
||||
receivers, and the recipients of class methods in superclasses.
|
||||
|
||||
|
||||
@subsection NSClassFromString
|
||||
|
||||
Class names are about the only names with global visibility in Objective-C.
|
||||
If a class is unknown at compilation but is available as a string at run time,
|
||||
@code{NSClassFromString} may be used to return the class object:
|
||||
|
||||
|
||||
@example
|
||||
..
|
||||
if ([anObject isKindOf: NSClassFromString(classTitle)] == YES)
|
||||
..
|
||||
@end example
|
||||
|
||||
The function returns nil if it is passed a string holding an invalid class name.
|
||||
Class names, global variables and function exist in the same
|
||||
name space, so classes and global variables may not share the same name.
|
||||
|
||||
@subsection respondsToSelector and NSStringFromClass
|
||||
|
||||
Run-time errors result when objects are stimulated to perform methods
|
||||
absent from their repertoire. These errors are avoided by checking the
|
||||
receiver's available methods, and if statically typed the compiler will
|
||||
report them. Testing for this error may be left until run-time when the
|
||||
message selector or the receiver's class varies.
|
||||
The @code{respondsToSelector:} method inspects a receiver for compatibility
|
||||
by sending them the method selector as an argument, and subsequently
|
||||
returning a verification.
|
||||
@example
|
||||
|
||||
if ([userObject respondsToSelector: @@selector(setOrigin::)] == YES)
|
||||
@{
|
||||
[userObject setOrigin: 2.0 : 2.0];
|
||||
@}
|
||||
else
|
||||
@{
|
||||
NSLog(@"%@ out of range", NSStringFromClass([userObject class]));
|
||||
@}
|
||||
@end example
|
||||
|
||||
@section Naming Conventions
|
||||
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Global variables may NOT share the same name as classes, because both
|
||||
entities are allocated the same name space.
|
||||
|
||||
@item
|
||||
Files with an .m extension hold Objective-C source code, while those with a
|
||||
.h extension define protocols, or define classes and category interfaces.
|
||||
|
||||
@item
|
||||
Implementation files have an @code{.m} extension.
|
||||
|
||||
@item
|
||||
Interface files have a @code{.h} extension.
|
||||
|
||||
@item
|
||||
Class, category and protocol names begin with an uppercase letter.
|
||||
|
||||
@item
|
||||
Methods, instance variables, and variables holding instances begin
|
||||
with a lowercase letter.
|
||||
|
||||
@item
|
||||
A class may define methods using the same names as those held in other classes.
|
||||
(See Overriding Methods.)
|
||||
|
||||
@item
|
||||
A class may define instance variables using the same names as those
|
||||
held in other classes.
|
||||
|
||||
@item
|
||||
A class category may have the same name as another class category.
|
||||
|
||||
@item
|
||||
An instance method and a class method may share the same name.
|
||||
|
||||
@item
|
||||
A protocol may have the same name as a class, category, or any other entity.
|
||||
|
||||
@item
|
||||
A method and an instance variable may share the same name.
|
||||
|
||||
@end itemize
|
||||
|
||||
@subsection Pitfalls of Using Class Names
|
||||
@emph{Richard to complete}@*
|
||||
(To be completed.)
|
||||
|
||||
@section The NSString Class
|
||||
|
||||
The NSString class defines objects holding character streams or @b{strings} using any spoken language. A
|
||||
@b{static} instance of NSString is allocated at compile time. The creation of a static
|
||||
instance of NSString is achieved using the @code{@@"..."} construct and a pointer:
|
||||
|
||||
@example
|
||||
NSString *wasp = @@"Brainstorm";
|
||||
@end example
|
||||
@code{wasp} is a variable that refers to an NSString object representing
|
||||
the ASCII string "Brainstorm".
|
||||
|
||||
@page
|
1028
Documentation/manual/WorkingWithObjects.texi
Normal file
1028
Documentation/manual/WorkingWithObjects.texi
Normal file
File diff suppressed because it is too large
Load diff
442
Documentation/manual/WritingNewClasses.texi
Normal file
442
Documentation/manual/WritingNewClasses.texi
Normal file
|
@ -0,0 +1,442 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Classes
|
||||
@chapter Writing New Classes
|
||||
@cindex writing new classes
|
||||
|
||||
@emph{Would you add Hands-on coding examples at the marked points, and perhaps any additional pertinent examples? Francis}@*
|
||||
|
||||
@section Interface
|
||||
@cindex interface
|
||||
|
||||
A class interface declares instance variables, methods and
|
||||
the superclass name, while the implementation file holds the
|
||||
operational code that implements those methods. The interface
|
||||
is included in the source using @code{#include}:
|
||||
|
||||
@example
|
||||
#include "baseclass.h"
|
||||
@end example
|
||||
|
||||
Typically the Interface and Implementation are held in separate files,
|
||||
using the .h and .m extensions, respectively. They may, however,
|
||||
be merged into one file, and a single file may implement many classes.
|
||||
|
||||
To ensure that a Header file is included only once, it is usual to
|
||||
protect it with pre-compiler defines:
|
||||
|
||||
@example
|
||||
#ifndef _MY_CLASS_H_INCLUDED
|
||||
#define _MY_CLASS_H_INCLUDED
|
||||
|
||||
/* HEADER FILE */
|
||||
#endif
|
||||
@end example
|
||||
|
||||
This is the standard C technique to protect header files from
|
||||
being included more than once.
|
||||
|
||||
@comment The role of the interface
|
||||
@subsection Interface Capabilities
|
||||
|
||||
The interface file declares new classes that can be used by
|
||||
source code, holding all the information necessary to use the
|
||||
classes from other Objective-C code. Firstly, the file reveals
|
||||
to the programmer the position of the class in the class hierarchy
|
||||
by defining exactly which is the superclass. Secondly, it informs
|
||||
programmers of what variables are inherited when they create subclasses.
|
||||
Finally, the interface file may inform other software entities
|
||||
of the messages that can be sent to the class object and to the
|
||||
instances of the class.
|
||||
|
||||
|
||||
@comment Writing an interface (syntax)
|
||||
The syntax of a class interface is of the form:
|
||||
|
||||
@emph{I would like a better example interface than this? So would you create something more real?}@*
|
||||
|
||||
@example
|
||||
// Need something here.
|
||||
@end example
|
||||
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The interface is enclosed between the compiler directives
|
||||
@code{@@interface} and @code{@@end}.
|
||||
|
||||
@item
|
||||
@code{@@interface ThisClass : ThisClassSuperClass} names the class
|
||||
and links it to the superclass. If no superclass is named, and the
|
||||
directive is without a colon, the compiler assumes that a root class
|
||||
is being created.
|
||||
|
||||
@item
|
||||
Braces enclose declared instance variables, each class' instance will
|
||||
have all theses instance variables including instance variables
|
||||
inherited from the superclass, and from the superclass of the
|
||||
superclass, extending to the root class.
|
||||
|
||||
@item
|
||||
Method declarations that begin with a "+" sign are class methods, and
|
||||
are defined for the class object.
|
||||
A class object inherits class methods from superclasses.
|
||||
|
||||
@item
|
||||
Method declarations that begin with a "-" sign are instance methods,
|
||||
and are defined for class instances. Class instances inherit instance
|
||||
methods from superclasses.
|
||||
|
||||
@item
|
||||
A method may share the name of an instance variable.
|
||||
|
||||
@item
|
||||
A method return type is declared using the standard C syntax:
|
||||
@example
|
||||
- (float) scale;
|
||||
@end example
|
||||
which is a method returning a float.
|
||||
|
||||
@item
|
||||
Argument types can be declared in the same way as method return types:
|
||||
@example
|
||||
- (void) setRadius: (float)aRadius;
|
||||
@end example
|
||||
which is a method that returns nothing, and takes a single float as
|
||||
its argument.
|
||||
|
||||
Note. The default type for methods and messages (@code{id}) is assumed
|
||||
when a return or argument type is not explicitly declared.
|
||||
For example, @code{-name;} implicitly means a method returning @code{id}
|
||||
(i.e. an object). It is usually better to avoid this and use
|
||||
explicit typing as in
|
||||
@example
|
||||
- (NSString*) name;
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@subsection Including Interfaces
|
||||
Source modules (including Objective-C listings and interface files)
|
||||
may integrate interfaces using @code{#include}. Thereafter the source
|
||||
module may utilize the classes in those interfaces so as to:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Make instances of them.
|
||||
|
||||
@item
|
||||
Send messages to invoke methods declared for them.
|
||||
|
||||
@item
|
||||
Refer to instance variables in them.
|
||||
|
||||
@end itemize
|
||||
|
||||
With the exception of the root class, all working interfaces
|
||||
integrate a superclass using either @code{#include} - as was
|
||||
seen in the previous simplified interface file example.
|
||||
As a result the vast majority of class files begin with a
|
||||
standard form that includes their superclasses, and thus
|
||||
places them in the class hierarchy:
|
||||
|
||||
@emph{ Here I have another example - would you replace it with something more meaningful?}
|
||||
|
||||
@example
|
||||
#include "Superclass.h"
|
||||
@@interface InterfaceName : InterfaceSuperclass
|
||||
@{
|
||||
// instance variables
|
||||
@}
|
||||
Declared methods
|
||||
@end example
|
||||
|
||||
@subsection Referring to Classes - @@class
|
||||
It is possible for a source module to refer to classes without
|
||||
including their interface files. This is useful when you just
|
||||
need to tell the compiler that a certain word is a class name,
|
||||
but you want to avoid the overhead of including the whole interface
|
||||
file for that class.
|
||||
|
||||
If you are implementing a new class, you always need to include
|
||||
the interface of the superclass using @code{#include};
|
||||
@code{@@class} cannot be used in this case because the compiler
|
||||
needs to know the details of the superclass and its instance
|
||||
variables etc., so as to create a fully working new class.
|
||||
If you try using @@class in this case, compilation will abort.
|
||||
|
||||
@b{Note. When you need to send methods to an object, it's better
|
||||
to include the full class interface. Even in that case - it's
|
||||
better *only* because it allows better type checking -
|
||||
which is good of course - but not essential. And - to say it
|
||||
all - if you use @@class that way, the compiler complains as soon
|
||||
as you try to send a message to an object of a class declared
|
||||
using @@class, so that you know you need to include the
|
||||
interface for full type checking. This means it's a good idea
|
||||
to always try with @@class if possible and only include the
|
||||
interface if the compiler complains that it can't type-check
|
||||
without the full interface.}
|
||||
|
||||
To inform the compiler that @b{Border} and @b{Square} are classes without including their full interface file, the following syntax is used:
|
||||
|
||||
@code{@@class Border, Square;}
|
||||
|
||||
Class names may also appear in interface files at times when
|
||||
instance variables, return values and arguments are statically typed:
|
||||
|
||||
- (void) set
|
||||
|
||||
|
||||
@emph{Another example of a class interface is required here, and perhaps an example of a class cluster would be useful as this is mentioned in chapter 1.}@*
|
||||
a simple example of a class interface <fixme: what example ?>
|
||||
|
||||
@section Implementation
|
||||
An interface file declares a class, while an implementation file
|
||||
implements it. The separation between the interface and
|
||||
implementation file yields a black box concept where the programmer
|
||||
using the class need only be concerned with the interface and its
|
||||
declared methods, superclasses, and instance variables.
|
||||
The implementation of classes is transparent to the programmer
|
||||
who may use them without detailed knowledge of their structures.
|
||||
|
||||
In the C programming language C structures are singular entities
|
||||
that encapsulate multiple data elements. The fields therein reside
|
||||
in @b{name spaces} so they do not interfere with alike named
|
||||
entities that are outside the structure. So the name spaces
|
||||
define another partition.
|
||||
|
||||
Such C structures relate to C functions that provide the
|
||||
application logic or defined mechanisms. Within a C structure
|
||||
data elements may be local to a function, and are protected in
|
||||
their name space.
|
||||
|
||||
@subsection Writing an Implementation
|
||||
An implementation file contents are encapsulated between
|
||||
@@implementation and @@end directives:
|
||||
|
||||
@example
|
||||
#include "ClassTitle .h"
|
||||
@@implementation ClassName :Superclass
|
||||
@{
|
||||
// instance variables
|
||||
@}
|
||||
// methods
|
||||
@@end
|
||||
@end example
|
||||
|
||||
The Implementation file uses @code{#include} to include a named
|
||||
interface file holding all declarations. Thereafter, the
|
||||
implementation need not declare instance variables, rather it
|
||||
may be dedicated to defining methods that may include a number
|
||||
of arguments; these are declared in the same way as the interface
|
||||
file but without the semicolon:
|
||||
|
||||
@comment - Could you add something more meaningful here?
|
||||
|
||||
@example
|
||||
@end example
|
||||
|
||||
|
||||
@subsection Referring to Instance Variables
|
||||
|
||||
When an instance method of a certain object is called, the method can
|
||||
refer to the object's instance variables directly by name.
|
||||
|
||||
The following example illustrates how a method definition refers to the
|
||||
receiving object's @b{instance variable} called @code{line}.
|
||||
|
||||
@example
|
||||
- (void) setLine: (BOOL)flag
|
||||
@{
|
||||
line = flag;
|
||||
@}
|
||||
@end example
|
||||
|
||||
You can access instance variables of other instances of the same class by using the operator @code{->}.
|
||||
|
||||
@emph{Example here.}
|
||||
|
||||
The following code fragment demonstrates how the GPRS class may declare a statically typed object as an instance variable called qosfive:
|
||||
|
||||
@example
|
||||
@@interface GPRS :NSObject
|
||||
@{
|
||||
Connect *qosfive;
|
||||
int frequency;
|
||||
struct features *chargeband;
|
||||
@}
|
||||
@end example
|
||||
|
||||
Because qosfive is typed to the same class, the instance variables of the statically typed class are in the scope of the class. So the Connect method may set them directly:
|
||||
|
||||
@example
|
||||
-makeAnotherQosfive
|
||||
@{
|
||||
if (!qosfive) @{
|
||||
qosfive =[[Connect alloc ] init ];
|
||||
qosfive->frequency =frequency;
|
||||
qosfive->chargeband =chargeband;
|
||||
@}
|
||||
return qosfive;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@b{Note. When the object is not a receiver, it is necessary that the object be @b{statically typed} in the class declaration.}
|
||||
|
||||
@c {the scope of instance variables (@@public, @@protected, @@private)}
|
||||
|
||||
@subsection Instance Variable Scope
|
||||
|
||||
In Objective-C instance variable have three types of @b{scope} or accessibility:
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{@@private} restricts the instance variable to the declaring class, and not to inheriting classes.
|
||||
|
||||
@item
|
||||
@code{@@protected} restricts the instance variable to the declaring class and inheriting
|
||||
classes - this is the default scope.
|
||||
|
||||
@item
|
||||
@code{@@public} globalises the instance variable, removing all the aforementioned restrictions.
|
||||
|
||||
@end itemize
|
||||
|
||||
|
||||
@subsection Accessing Object Data Structures
|
||||
The instance variables or data structures of objects are accessed by sending the object messages. An Objective-C object's instance variables may be changed to a @b{public} scope by converting them into a C structure.
|
||||
|
||||
|
||||
The @code{@@defs(className)} directive produces a declaration list, where @code{public} is used as a pointer to the structure that approximates an instance of @code{Gprschannel}:
|
||||
|
||||
@example
|
||||
struct gprschannelDef @{
|
||||
@@defs(Gprschannel)
|
||||
@}*public;
|
||||
@end example
|
||||
|
||||
An object's instance variables may be given @b{public scope} through a @code{Gprschannel id} assigned to the pointer:
|
||||
@example
|
||||
id aGprschannel;
|
||||
aWorker =[[Gprschannel alloc ] init ];
|
||||
public =(struct gprschannelDef *)aGprschannel;
|
||||
public->boss =nil;
|
||||
@end example
|
||||
|
||||
|
||||
@comment examples, with messages to self and super
|
||||
|
||||
@comment Messages to Self and Super
|
||||
|
||||
|
||||
@subsection Super and Self
|
||||
|
||||
In the implementation of an Objective-C method, you may use the two reserved words @b{self} and @b{super}
|
||||
|
||||
@emph{example here}
|
||||
.
|
||||
In Objective-C some control over messaging is provided by @b{self} and @b{super}. @b{Self} searches for the
|
||||
method implementation in the receiving object's class.
|
||||
|
||||
@b{Super} begins searching for the method implementation in the superclass of the class that defines the method with super.
|
||||
|
||||
A method implementation may refer to the target object as @b{self} or @b{super}, where
|
||||
control is provided over which object performs the method.
|
||||
|
||||
To demonstrate the difference between @b{self} and @b{super} consider three classes:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
One
|
||||
|
||||
@item
|
||||
Two - One's superclass
|
||||
|
||||
@item
|
||||
Three - Two's superclass
|
||||
@end itemize
|
||||
|
||||
All three classes define a method called @b{traffic}, while Two defines a method called @b{Alert} that depends on @b{traffic}.
|
||||
|
||||
Sending a message to the One object to invoke the @b{Alert} method, causes the @b{Alert} method to send a @b{traffic} message to the same One object.
|
||||
|
||||
The following source code would search for the traffic method defined in One (or self's class).
|
||||
|
||||
@example
|
||||
-Alert
|
||||
@{
|
||||
[self traffic ];
|
||||
...
|
||||
@}
|
||||
@end example
|
||||
|
||||
|
||||
When Two’s source code calls this object super, the messaging routine will find the version of traffic defined in Three (the @b{superclass} of Two).
|
||||
|
||||
@example
|
||||
-Alert
|
||||
@{
|
||||
[super traffic ];
|
||||
...
|
||||
@}
|
||||
@end example
|
||||
|
||||
|
||||
@b{Self} is a variable name that may be assigned new values particularly in definitions
|
||||
of class methods that often focus on class instances as opposed to class objects. For example,
|
||||
a method might combine allocation and initialization of an instance:
|
||||
|
||||
@example
|
||||
|
||||
+(id)newRect
|
||||
@{
|
||||
return [[self alloc ] init ];
|
||||
@}
|
||||
|
||||
@end example
|
||||
|
||||
|
||||
When in class methods self refers to class objects, and when in instance methods self
|
||||
refers to instances. @b{self} and @b{super} focus on the receiver that is the object
|
||||
being stimulated by a message.
|
||||
|
||||
|
||||
@emph{Nicola/Richard add an example for self and super here - or two examples?}
|
||||
|
||||
implementation of the example class interface
|
||||
|
||||
@section Categories
|
||||
A category may serve to replace a subclass; when adding methods to an existing declared class, and not to a new class, a @b{category name} is used.
|
||||
An interface file may declare methods under a category name that is also used in the implementation file for the definitions of those methods.
|
||||
Category methods are added to the class, and instances of the class will have the methods as part of their behaviour. As is the case with other methods, category methods are inherited by all the class' subclasses.
|
||||
|
||||
@subsection Adding to Classes
|
||||
|
||||
A category interface has the form:
|
||||
|
||||
@example
|
||||
#include "ClassTitle .h"
|
||||
@@interface ClassTitle (CategoryTitle )
|
||||
declared methods
|
||||
@@end
|
||||
@end example
|
||||
|
||||
The category may include a interface, so as to allow its methods to access the instance variables of named classes.
|
||||
|
||||
A category implementation file has the form:
|
||||
|
||||
@example
|
||||
#include "CategoryTitle .h"
|
||||
@@implementation ClassTitle (CategoryTitle )
|
||||
definitions of methods
|
||||
@@end
|
||||
@end example
|
||||
|
||||
Category methods may replace the conventional methods inherited by the class.
|
||||
|
||||
@b{Note. A category should not be considered a substitute for a subclass. }
|
||||
|
||||
@subsection Using Categories
|
||||
Categories are useful for extending existing classes, so as to add new methods to frameworks. Categories are often used to separate the implementation of a new class into a number of source files. The obvious benefits of this program development strategy include: grouping subject-oriented methods; incremental compilation for large classes; help to logically divide the class when being created by a number of developers; and, permit configuration-specific classes targeting particular applications.
|
||||
|
||||
|
||||
@page
|
BIN
Documentation/manual/chap5-1-Forwarding.eps
Normal file
BIN
Documentation/manual/chap5-1-Forwarding.eps
Normal file
Binary file not shown.
33
Documentation/manual/foreword.texi
Normal file
33
Documentation/manual/foreword.texi
Normal file
|
@ -0,0 +1,33 @@
|
|||
@c Foreword
|
||||
@unnumbered Foreword
|
||||
|
||||
The aim of this document is to provide a GNUstep/Objective-C programming
|
||||
manual (primarily tutorial in style) for the language, the GNUstep
|
||||
base library, and the GNUstep makefiles package.
|
||||
|
||||
The manual does not cover installation instructions as these vary from
|
||||
system to system, and are documented fairly well in the GNUstep HOWTO (http://www.gnustep.org).
|
||||
|
||||
What we want is a manual to tell programmers how to use the system,
|
||||
particularly how to program with the base library in Objective-C,
|
||||
but also to some extent from Java and Guile.
|
||||
|
||||
The target audience for this manual is the C, C++, or Java programmer
|
||||
that wishes to learn to use Objective-C effectively. We assume that,
|
||||
while the reader is able to understand English, it is quite possibly
|
||||
not their native language.
|
||||
|
||||
For detailed class reference documentation the reader is directed to the GNUstep Base Library documentation (http://www.gnustep.org), and to the Apple Cocoa Objective-C Foundation documentation (http://www.apple.com).
|
||||
|
||||
Other reference documentation is -
|
||||
@itemize @bullet
|
||||
@item GNUstep-Java interface (documented as part of JIGS)
|
||||
@item GNUstep-Guile interface (documented as part of gstep-guile)
|
||||
@item Installation/configuration (documented in GNUstep HOWTO)
|
||||
@end itemize
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
60
Documentation/manual/index.html
Normal file
60
Documentation/manual/index.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org" />
|
||||
<title>
|
||||
GNUstep Objective-C programming manual
|
||||
</title>
|
||||
</head>
|
||||
<body background="/images/swirl.jpg">
|
||||
<div align="center">
|
||||
<img src="/images/newlogo.jpg" alt="Brainstorm logo" />
|
||||
<p>
|
||||
$Revision$ $Date$
|
||||
</p>
|
||||
</div>
|
||||
<h1>
|
||||
Brainstorm Objective-C programming manual
|
||||
</h1>
|
||||
<p>
|
||||
The aim of this manual is to provide a tutorial and reference
|
||||
manual to the use of the Objective-C language with the
|
||||
GNUstep-base library. We want it to be readable enough for
|
||||
programmers with a reasonable understanding of C or Java ...
|
||||
even if english is not the programmers first/main language.
|
||||
We also want it to cover the language in enough depth to
|
||||
teach people how to get its full benefits, and understand its
|
||||
use in the Brainstorm software environment.
|
||||
</p>
|
||||
<p>
|
||||
The programing manual is a work in progress. At the time of
|
||||
writing this, I believe that the overall structure is roughly
|
||||
correct and the actual content of the document is perhaps one
|
||||
third filled in. Once the content is complete, the document
|
||||
will probably need a good bit of editorial work to make it
|
||||
more readable and to check consistency etc.
|
||||
</p>
|
||||
<p>
|
||||
The manual source is in texinfo format ... and is built
|
||||
automatically to info, html, and postscript format.
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="manual_toc.html">Read the HTML version online</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="manual.ps">Download the PostScript version</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Please send comments/criticisms/corrections to <a
|
||||
href="mailto:richard@brainstorm.co.uk">richard@brainstorm.co.uk</a>
|
||||
or <a
|
||||
href="mailto:nicola@brainstorm.co.uk">nicola@brainstorm.co.uk</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
138
Documentation/manual/manual.texi
Normal file
138
Documentation/manual/manual.texi
Normal file
|
@ -0,0 +1,138 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
|
||||
@c %**start of header
|
||||
@setfilename manual.info
|
||||
@settitle Objective-C, Programming Manual
|
||||
@c %**end of header
|
||||
|
||||
@ifinfo
|
||||
@format
|
||||
START-INFO-DIR-ENTRY
|
||||
* GNUstepBase: Objective C Language and GNUstep Base Library
|
||||
END-INFO-DIR-ENTRY
|
||||
@end format
|
||||
@end ifinfo
|
||||
|
||||
@ifinfo
|
||||
Copyright @copyright{} 2001 Free Software Foundation
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided also that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions.
|
||||
@end ifinfo
|
||||
|
||||
@setchapternewpage odd
|
||||
@titlepage
|
||||
|
||||
@title Objective-C Language
|
||||
@title and GNUstep Base Library
|
||||
@title Programming Manual
|
||||
|
||||
@author Francis Botto (Brainstorm)
|
||||
@author Richard Frith-Macdonald (Brainstorm)
|
||||
@author Nicola Pero (Brainstorm)
|
||||
@page
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 2001 Free Software Foundation
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided also that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions.
|
||||
@end titlepage
|
||||
|
||||
@contents
|
||||
|
||||
@iftex
|
||||
@c Foreword
|
||||
@include foreword.texi
|
||||
@end iftex
|
||||
|
||||
@ifinfo
|
||||
@c **Top node and master menu
|
||||
@node Top
|
||||
@top Objective-C Programming Manual
|
||||
|
||||
@include foreword.texi
|
||||
|
||||
@menu
|
||||
* Introduction:: An introduction to object-oriented programming
|
||||
* Objective-C:: An introduction to the Objective-C language
|
||||
* Classes:: How to create a new class
|
||||
* Objects:: Working with objects
|
||||
* Distributed Objects:: Working with distributed objects
|
||||
* Advanced Topics:: Topics that take you deeper into Objective-C
|
||||
|
||||
* Glossary:: Glossary of Terms
|
||||
* Examples:: Examples of Objective-C code
|
||||
* Make:: The GNUstep Make package
|
||||
* Obj-C and Java:: Differences and similarities between Objective-C and Java
|
||||
* Java and Guile:: Programming GNUstep in Java and Guile
|
||||
@end menu
|
||||
@c **end Top node and master menu
|
||||
@end ifinfo
|
||||
|
||||
@page
|
||||
|
||||
@c Chapter 1, Introduction
|
||||
@include Introduction.texi
|
||||
|
||||
@c Chapter 2, The Objective-C Language
|
||||
@include ObjcLanguage.texi
|
||||
|
||||
@c Chapter 3, Writing New Classes
|
||||
@include WritingNewClasses.texi
|
||||
|
||||
@c Chapter 4, Working with Objects
|
||||
@include WorkingWithObjects.texi
|
||||
|
||||
@c Chapter 5, Distributed Objects
|
||||
@include DistributedObjects.texi
|
||||
|
||||
@c Chapter 6, Advanced Topics
|
||||
@include AdvancedTopics.texi
|
||||
|
||||
@c Appendix A: Glossary of Terms
|
||||
@include Glossary.texi
|
||||
|
||||
@c Appendix B: Example Code
|
||||
@include ExampleCode.texi
|
||||
|
||||
@c Appendix C: Using the GNUstep make package
|
||||
@include GNUstepMake.texi
|
||||
|
||||
@c Appendix D: Comparison between Objective-C and Java
|
||||
@include ObjcAndJava.texi
|
||||
|
||||
@c Appendix E: Programming GNUstep in Java and Guile
|
||||
@include JavaAndGuile.texi
|
||||
|
||||
|
||||
@unnumbered Concept Index
|
||||
@printindex cp
|
||||
|
||||
@bye
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue