mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
major manual update, filling in missing sections, reorganizing topics
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19583 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
6255bcadf0
commit
11c3f06af0
12 changed files with 2364 additions and 2156 deletions
|
@ -56,7 +56,7 @@ communication or 'remote messaging'.
|
|||
@cindex NSRunLoop class
|
||||
|
||||
GNUstep overcomes these limitations by providing you with classes that
|
||||
form, what is known as, a 'distributed objects' architecture 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
|
||||
|
@ -90,34 +90,39 @@ 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
|
||||
@cindex distributed objects, client 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.
|
||||
In order to respond to client messages, the responding server object must be
|
||||
set as the 'root object' of an instance of the @code{NSConnection} class, and
|
||||
this @code{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 @code{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.
|
||||
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 @code{NSRunLoop} class. Since an
|
||||
@code{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
|
||||
When the runloop detects an incoming message, the message is passed to the
|
||||
root object of the @code{NSConnection}, which performs a method in response to
|
||||
the message and returns a variable of the appropriate type. The
|
||||
@code{NSConnection} manages all inter-process communication, decoding incoming
|
||||
messages and encoding any returned values.
|
||||
@comment{Sequence diagram would be really useful here.}
|
||||
|
||||
The code to vend the @code{telephoneDirectory} object and start the
|
||||
runloop would look something like this:
|
||||
|
||||
@example
|
||||
/*
|
||||
* The main() function: Set up the program
|
||||
* as a 'Distributed Objects Server'.
|
||||
*/
|
||||
int main(void)
|
||||
@{
|
||||
/*
|
||||
* Remember, create an instance of the
|
||||
* NSAutoreleasePool class.
|
||||
|
@ -152,17 +157,18 @@ runloop would look something like this:
|
|||
|
||||
/* Release the pool */
|
||||
RELEASE(pool);
|
||||
return 0;
|
||||
@}
|
||||
@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
|
||||
@cindex distributed objects, 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
|
||||
server object, using the name that was registered for the @code{NSConnection}
|
||||
at the server.
|
||||
|
||||
@example
|
||||
|
@ -171,9 +177,9 @@ at the server.
|
|||
|
||||
/* Get the proxy */
|
||||
id proxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@i{registeredServerName}
|
||||
host: @i{hostName}];
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@i{registeredServerName}
|
||||
host: @i{hostName}];
|
||||
|
||||
/* The rest of your program code goes here */
|
||||
|
||||
|
@ -186,16 +192,16 @@ 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.
|
||||
local 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: "*"];
|
||||
rootProxyForConnectionWithRegisteredName:
|
||||
@@"DirectoryServer"
|
||||
host: "*"];
|
||||
@end example
|
||||
|
||||
With this additional line of code in the client program, you can now
|
||||
|
@ -206,6 +212,7 @@ object.
|
|||
NSString *wantedNumber = [proxyForDirectory teleNumber: personName];
|
||||
@end example
|
||||
|
||||
|
||||
@subsection Using a Protocol
|
||||
@cindex protocol for distributed objects
|
||||
@cindex distributed objects, using a protocol
|
||||
|
@ -258,68 +265,163 @@ 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
|
||||
|
||||
@subsection Complete Code for Telephone Directory Application
|
||||
|
||||
Here we provide the rest of the code needed for client and server to actually
|
||||
run the above example.
|
||||
|
||||
@b{Code At 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
|
||||
|
||||
/* main() function: Set up the program as a 'Distibuted Objects Server'. */
|
||||
/* [use code from server example above ...] */
|
||||
@end example
|
||||
|
||||
@b{Code at Client}
|
||||
|
||||
|
||||
@example
|
||||
#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);
|
||||
|
||||
/* Acquire the remote reference. */
|
||||
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
|
||||
|
||||
To get this running, all you need do is create two directories, one for the
|
||||
client and one for the server. Each directory will hold a makefile, the client
|
||||
or server source code, and a copy of the protocol header file. When the files
|
||||
compile, first run the server and then the client. You can try this on the
|
||||
same machine, or on two different machines (with GNUstep installed) on the
|
||||
same LAN. What happens when you run the client without the server? How would
|
||||
you display a "No Server Connection" warning at the client?
|
||||
|
||||
|
||||
@subsection GNUstep Distributed Objects Name Server
|
||||
@cindex gdomap
|
||||
@cindex Distributed Objects Name Server, GNUstep
|
||||
|
||||
You might wonder how the client finds the server, or, rather, how it finds the
|
||||
directory the server lists itself in. In fact an auxiliary process will
|
||||
automatically be started on each machine, if it isn't running already, that
|
||||
handles this, allowing the server to register and the client to send a query
|
||||
behind the scenes. This @i{GNUstep Distributed Objects Name Server} runs as
|
||||
'@code{gdomap}' and binds to port 538. See the manual page or the HTML
|
||||
``GNUstep Base Tools'' @uref{../../Tools/Reference/index.html,
|
||||
documentation} for further information.
|
||||
|
||||
|
||||
@subsection Look Ma, No Stubs!
|
||||
|
||||
One difference you may have noticed in the example we just looked at from
|
||||
other remote method invocation interfaces such as CORBA and Java RMI was that
|
||||
there are @i{no stub classes}. The source of this great boon is described at
|
||||
the end of this chapter: @ref{Distributed Objects, , Language Support for
|
||||
Distributed Objects}.
|
||||
|
||||
|
||||
@section A More Involved Example
|
||||
@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.
|
||||
Now we will look at an example called GameServer that uses distributed objects
|
||||
in a client/server game.
|
||||
|
||||
Actually the game itself is not implemented, just its distributed support
|
||||
structure, 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. Here
|
||||
are the requirements we will implement:
|
||||
|
||||
@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
|
||||
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
|
||||
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).@*@*
|
||||
@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.
|
||||
Have a look at the program code in the following sections 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 @uref{../Reference/index.html, here} or at the Apple
|
||||
web site.
|
||||
|
||||
|
||||
@subsection Protocol Adopted at Client
|
||||
|
||||
|
@ -471,17 +573,19 @@ int main(int argc, char **argv)
|
|||
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 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
|
||||
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.
|
||||
@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
|
||||
|
@ -718,40 +822,45 @@ int main(int argc, char** argv)
|
|||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
@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?
|
||||
re-join a game after losing? 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.
|
||||
remote process. (See @ref{Advanced Messaging, , Forwarding}.)
|
||||
|
||||
|
||||
@subsection Protocol Type Qualifiers
|
||||
@cindex protocol type qualifiers
|
||||
|
@ -759,6 +868,7 @@ remote process.
|
|||
@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
|
||||
|
@ -891,19 +1001,21 @@ individual object).
|
|||
@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.
|
||||
If you have used other remote invocation mechanisms such as CORBA or Java
|
||||
RMI, you may have noticed a big difference from these in the GNUstep
|
||||
Distributed Object paradigm -- there are no ``stub'' classes, either on the
|
||||
client or the server. This tremendously simplifies the use of remote
|
||||
invocation and is possible due to the Objective-C message-forwarding facility
|
||||
(@ref{Advanced Messaging, , Forwarding}).
|
||||
|
||||
In GNUstep, there are proxies on the client and server side that handle
|
||||
network communications and serialization/deserialization of arguments and
|
||||
return values just as in CORBA and RMI, but when it comes to responding to the
|
||||
client and server protocol method calls themselves, they are intercepted
|
||||
through the use of the @code{forwardInvocation:} method, where they can be
|
||||
passed on to the registered client and server objects through the ordinary
|
||||
Objective-C message sending mechanism.
|
||||
|
||||
|
||||
@section Error Checking
|
||||
|
@ -941,7 +1053,8 @@ 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.
|
||||
@code{object} message. See @ref{Base Library, , Event-Based Communications}
|
||||
for more information on notifications.
|
||||
|
||||
To receive this 'notification' the observer must implement the
|
||||
@code{connectionDidDie:} method, but can be an instance of any class. The
|
||||
|
@ -950,11 +1063,8 @@ 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.
|
||||
@comment{Need some comments on reference counting and disposal.}
|
||||
|
||||
|
||||
@page
|
||||
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
@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 ***
|
|
@ -6,19 +6,21 @@ GNUSTEP_MAKEINFO_FLAGS = -D NO-TEXI2HTML
|
|||
DOCUMENT_NAME = manual
|
||||
|
||||
manual_TEXI_FILES = \
|
||||
manual.texi \
|
||||
foreword.texi \
|
||||
Introduction.texi \
|
||||
ObjcLanguage.texi \
|
||||
WritingNewClasses.texi \
|
||||
WorkingWithObjects.texi \
|
||||
manual.texi \
|
||||
AdvancedMessaging.texi \
|
||||
BaseLibrary.texi \
|
||||
Compliance.texi \
|
||||
DistributedObjects.texi \
|
||||
AdvancedTopics.texi \
|
||||
Glossary.texi \
|
||||
ExampleCode.texi \
|
||||
ExceptionHandling.texi \
|
||||
GNUstepMake.texi \
|
||||
ObjcAndJava.texi \
|
||||
JavaAndGuile.texi
|
||||
GSDoc.texi \
|
||||
Introduction.texi \
|
||||
ObjcAndJavaC++.texi \
|
||||
ObjcLanguage.texi \
|
||||
JavaAndGuile.texi \
|
||||
WorkingWithObjects.texi \
|
||||
WritingNewClasses.texi
|
||||
|
||||
manual_DOC_INSTALL_DIR = Developer/Base/ProgrammingManual
|
||||
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
@paragraphindent 0
|
||||
|
||||
@node Glossary
|
||||
@appendix Glossary
|
||||
@cindex glossary
|
||||
|
||||
@c /* Empty glossary (to be completed). */
|
||||
|
||||
|
||||
Object
|
||||
|
||||
|
||||
Class
|
||||
|
||||
|
||||
Inheritance
|
||||
|
||||
|
||||
Polymorphism
|
||||
|
||||
|
||||
Encapsulation
|
||||
|
||||
|
||||
Invoke
|
||||
|
||||
|
||||
Method
|
||||
|
||||
|
||||
Makefile
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -3,73 +3,149 @@
|
|||
@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.
|
||||
The aim of this manual is to introduce you to the Objective-C language and the
|
||||
GNUstep development environment, in particular the Base library. The manual is
|
||||
organised to give you a tutorial introduction to the language and APIs, by
|
||||
using examples whenever possible, rather than providing a lengthy abstract
|
||||
description.
|
||||
|
||||
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.
|
||||
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,
|
||||
and comparisons to other languages will be used to aid in illustration.
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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
|
||||
@b{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.
|
||||
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++.)
|
||||
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
|
||||
@b{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.
|
||||
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.
|
||||
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
|
||||
@b{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).
|
||||
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.
|
||||
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
|
||||
@b{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.
|
||||
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.
|
||||
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
|
||||
@b{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.
|
||||
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.
|
||||
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
|
||||
@b{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).
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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>
|
||||
|
@ -84,40 +160,189 @@ int main (void)
|
|||
@}
|
||||
@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.
|
||||
Objective-C source files are compiled using the standard GNU @b{gcc}
|
||||
compiler. The compiler recognises Objective-C source files by the @code{.m}
|
||||
file extension, C files by the @code{.c} extension and header files by the
|
||||
@code{.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.
|
||||
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. (On GNU/Linux systems you may
|
||||
also need the @code{-lpthreads} option.)
|
||||
|
||||
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.
|
||||
|
||||
Relative to other languages, Objective-C is more dynamic than C++ or Java in
|
||||
that it binds all method calls at runtime. Java gets around some of the
|
||||
limitations of static binding with explicit runtime ``reflection'' mechanisms.
|
||||
Objective-C has these too, but you do not need them as often as in Java, even
|
||||
though Objective-C is compiled while Java is interpreted. More information
|
||||
can be found in Appendix @ref{Objective-C Java and C++}.
|
||||
|
||||
@section History
|
||||
@cindex history of Objective-C
|
||||
@cindex Objective-C, history
|
||||
@cindex history of NeXTstep
|
||||
@cindex NeXTstep, history
|
||||
@cindex history of OpenStep
|
||||
@cindex OpenStep, history
|
||||
|
||||
Objective-C was specified and first implemented by Brad Cox and his company
|
||||
Stepstone Corporation during the early 1980's. They aimed to minimally
|
||||
incorporate the object-oriented features of Smalltalk-80 into C. Steve Jobs's
|
||||
NeXT licensed Objective-C from StepStone in 1988 to serve as the foundation of
|
||||
the new NeXTstep development and operating environment. NeXT implemented its
|
||||
own compiler by building on the @i{gcc} compiler, modifications that were
|
||||
later contributed back to gcc in 1991. No less than three runtime libraries
|
||||
were subsequently written to serve as the GNU runtime; the one currently in
|
||||
use was developed by Danish university student Kresten Krab Thorup.
|
||||
|
||||
Smalltalk-80 also included a class library, and Stepstone's Objective-C
|
||||
implementation contained its own library based loosely on it. This in turn
|
||||
influenced the design of the NeXTstep class libraries, which are what GNUstep
|
||||
itself is ultimately based on.
|
||||
|
||||
After NeXT exited the hardware business in the early 1990s, its Objective-C
|
||||
class library and development environment, @i{NeXTstep}, was renamed
|
||||
@i{OpenStep} and ported to run on several different platforms. Apple acquired
|
||||
NeXT in 1996, and after several years figuring out how to smooth the
|
||||
transition from their current OS, they released a modified, enhanced version
|
||||
of the NeXTstep operating system as Mac OS X, or ``10'' in 1999. The class
|
||||
libraries in OS X contain additions related to new multimedia capabilities and
|
||||
integration with Java, but their core is still essentially the OpenStep API.
|
||||
|
||||
This API consists of two parts: the @i{Foundation}, a collection of
|
||||
non-graphical classes for data management, network and file interaction, date
|
||||
and time handling, and more, and the @i{AppKit}, a collection of user
|
||||
interface widgets and windowing machinery for developing full-fledged
|
||||
graphical applications. GNUstep provides implementations of both parts of
|
||||
this API, together with a graphical engine for rendering AppKit components on
|
||||
various platforms.
|
||||
|
||||
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.
|
||||
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. It is split into three
|
||||
components: @b{Base}, non-graphical classes corresponding to the NeXTstep
|
||||
@i{Foundation} API, @b{GUI}, consisting of graphical classes corresponding to
|
||||
the NeXTstep @i{AppKit} API, and @b{Back}, a modular framework for rendering
|
||||
instance of the GUI classes on multiple platforms.
|
||||
|
||||
GNUstep is generally compatible with the OpenStep specification and with
|
||||
recent developments of the MacOS (Cocoa) API. Where MacOS deviates from the
|
||||
OpenStep API, GNUstep generally attempts to support both versions. See
|
||||
Appendix @ref{Compliance to Standards} for more detailed information.
|
||||
|
||||
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://gnustep.org}.
|
||||
|
||||
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).
|
||||
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). It is similar to but more stable than the
|
||||
non-graphical portion of the Java Development Kit (JDK) API (see Appendix
|
||||
@ref{Objective-C Java and C++} for more information).
|
||||
|
||||
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 see the @uref{../Reference/index.html, API documentation}.
|
||||
|
||||
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
|
||||
@cindex make utility, GNUstep
|
||||
|
||||
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).
|
||||
The GNUstep @b{make} utility is the GNU version of the UNIX make utility, plus
|
||||
a number of predefined rules specialized for building GNUstep projects. 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). It also takes care of including the proper
|
||||
GNUstep header and library references automatically.
|
||||
|
||||
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.
|
||||
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. For a full description of the make utility see its
|
||||
@uref{../../Make/Manual/make_toc.html, documentation}.
|
||||
|
||||
@subsection A Word on the Graphical Environment
|
||||
@cindex graphical programming
|
||||
@cindex AppKit
|
||||
@cindex GUI
|
||||
|
||||
The GNUstep @b{GUI} component is discussed
|
||||
@uref{../../Gui/ProgrammingManual/manual_toc.html, elsewhere}), but a brief
|
||||
overview is useful here. GNUstep GUI provides a collection of classes for
|
||||
developing graphical applications, including windows, widgets, and back-end
|
||||
components for event handling and other functions. Internally, the
|
||||
implementation is divided into two components, the @i{back end} and the
|
||||
@i{front end}. The front end provides the API to the developer, and makes
|
||||
display postscript (DPS) calls to the back end to implement it. The back-end
|
||||
converts the DPS calls into calls to the underlying window system. If you
|
||||
install GNUstep from source, you must first compile and install the front end,
|
||||
then compile and install the back end.
|
||||
|
||||
Implementations of the back-end have been produced for both X11 (Linux/UNIX
|
||||
systems), and Windows. There is also a quasi-native display postscript system
|
||||
similar to what was available on the NeXT but using Ghostscript to render to
|
||||
X11. This implementation is largely complete, but proved to be inefficient
|
||||
and difficult to optimize relative to the current back-end framework (which
|
||||
converts the DPS from the front end to window drawing commands immediately
|
||||
rather than relying on a postscript stack).
|
||||
|
||||
@comment{Add brief blurbs on Gorm and Renaissance.}
|
||||
|
||||
|
||||
@subsection The GNUstep Directory Layout
|
||||
@cindex directory layout
|
||||
@cindex filesystem layout
|
||||
@cindex layout, filesystem
|
||||
|
||||
The directories of a GNUstep installation are organized in a fashion that
|
||||
balances compatibility with NeXTstep/OpenStep/OS X with traditional Unix
|
||||
filesystem conventions. The highest level of organization consists of four
|
||||
@i{domains} - the System, Local, Network, and Users. @i{System} holds the
|
||||
main GNUstep installation, including the Base and GUI libraries and
|
||||
documentation. @i{Local} holds third party applications, custom extension
|
||||
libraries, etc., analogously to @code{/usr/local} on a Unix system.
|
||||
@i{Network} mounts shared files in a networked environment. @i{Users} usually
|
||||
exists as @code{$HOME/GNUstep} and holds preferences files and personal
|
||||
application data. There is further
|
||||
@uref{../../../User/GNUstep/filesystem_toc.html, documentation} available on
|
||||
the complete directory layout.
|
||||
|
||||
Usually, on a Unix-type system, the GNUstep installation will be found under
|
||||
@code{/usr/lib/GNUstep}.
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
|
@ -166,14 +391,23 @@ int main(void)
|
|||
@}
|
||||
@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?@*@*
|
||||
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.@*@*
|
||||
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}.
|
||||
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
|
||||
|
@ -184,16 +418,42 @@ 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.@*@*
|
||||
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.@*@*
|
||||
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.@*@*
|
||||
Before you can execute this makefile you must first set your GNUstep
|
||||
environment variables. Among other things this defines the
|
||||
@code{GNUSTEP_MAKEFILES} variable referenced above. The simplest way to do
|
||||
this is to execute one of the following commands (you must first locate your
|
||||
GNUstep installation manually):
|
||||
|
||||
C shell:@*
|
||||
@code{source <GNUstep root>/System/Makefiles/GNUstep.csh}
|
||||
|
||||
Bourne shell:@*
|
||||
@code{. <GNUstep root>/System/Makefiles/GNUstep.sh}
|
||||
|
||||
On most Unix systems, GNUstep is installed in @code{/usr/lib/GNUstep}.
|
||||
(@uref{../../../User/GNUstep/filesystem_toc.html, Directory layout
|
||||
documentation}.)
|
||||
|
||||
@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).
|
||||
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 (on Unix 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.
|
||||
You have now compiled and run your first Objective-C program. Hungry for more?
|
||||
Then read on.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
@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.
|
||||
@i{TBD}
|
||||
|
||||
@page
|
||||
|
|
|
@ -1,218 +0,0 @@
|
|||
@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
|
||||
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,30 +1,24 @@
|
|||
@c Foreword
|
||||
@unnumbered Foreword
|
||||
@c @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.
|
||||
manual (primarily tutorial in style) for the language, the GNUstep Base
|
||||
library, and the GNUstep Make package. While to focus is on Objective-C, the
|
||||
GNUstep libraries can also be used from Java and Guile, and some information
|
||||
on this usage is also included.
|
||||
|
||||
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).
|
||||
The manual does not cover installation instructions as these vary from system
|
||||
to system, and are documented fairly well in the GNUstep
|
||||
@uref{../../../User/GNUstep/gnustep-howto_toc.html, HOWTO}.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
For detailed class reference documentation the reader is directed to the
|
||||
GNUstep Base Library @uref{../Reference/index.html, , documentation}, and to
|
||||
the Apple Cocoa Objective-C Foundation documentation (available through
|
||||
@url{http://www.apple.com}).
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -39,10 +39,11 @@ into another language, under the above conditions for modified versions.
|
|||
@author Francis Botto (Brainstorm)
|
||||
@author Richard Frith-Macdonald (Brainstorm)
|
||||
@author Nicola Pero (Brainstorm)
|
||||
@author Adrian Robert
|
||||
@page
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 2001 Free Software Foundation
|
||||
Copyright @copyright{} 2001-2004 Free Software Foundation
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
|
@ -61,7 +62,6 @@ into another language, under the above conditions for modified versions.
|
|||
|
||||
@ifnothtml
|
||||
@iftex
|
||||
@c Foreword
|
||||
@include foreword.texi
|
||||
@end iftex
|
||||
@end ifnothtml
|
||||
|
@ -77,16 +77,17 @@ into another language, under the above conditions for modified versions.
|
|||
@menu
|
||||
* Introduction:: An introduction to object-oriented programming
|
||||
* Objective-C:: An introduction to the Objective-C language
|
||||
* Objects:: Working with objects; memory management
|
||||
* Classes:: How to create a new class
|
||||
* Objects:: Working with objects
|
||||
* Advanced Messaging:: How messaging works, and advanced techniques
|
||||
* Exception Handling:: Exception handling, assertion, and logging facilities
|
||||
* 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
|
||||
* Base Library:: Using the classes in the GNUstep Base library
|
||||
* GSDoc:: The GNUstep documentation system
|
||||
* Bundles and Frameworks::The GNUstep Applicaton Resource Framework
|
||||
* Objective-C Java and C++:: Comparison between Objective-C, Java, and C++
|
||||
* Java and Guile:: Programming GNUstep in Java and Guile
|
||||
* Compliance to Standards:: GNUstep and the OpenStep and Mac OS X APIs
|
||||
@end menu
|
||||
@c **end Top node and master menu
|
||||
@end ifinfo
|
||||
|
@ -99,43 +100,42 @@ into another language, under the above conditions for modified versions.
|
|||
@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
|
||||
@c Chapter 3, Working with Objects
|
||||
@include WorkingWithObjects.texi
|
||||
|
||||
@c Chapter 5, Distributed Objects
|
||||
@c Chapter 4, Writing New Classes
|
||||
@include WritingNewClasses.texi
|
||||
|
||||
@c Chapter 5, Advanced Messaging
|
||||
@include AdvancedMessaging.texi
|
||||
|
||||
@c Chapter 6, Exception Handling, Assertions, and Logging
|
||||
@include ExceptionHandling.texi
|
||||
|
||||
@c Chapter 7, Distributed Objects
|
||||
@include DistributedObjects.texi
|
||||
|
||||
@c Chapter 6, Advanced Topics
|
||||
@include AdvancedTopics.texi
|
||||
@c Chapter 8, Base Library
|
||||
@include BaseLibrary.texi
|
||||
|
||||
@c Appendix A: Glossary of Terms
|
||||
@include Glossary.texi
|
||||
@c Appendix A: GSDoc
|
||||
@include GSDoc.texi
|
||||
|
||||
@c Appendix B: Example Code
|
||||
@include ExampleCode.texi
|
||||
@c Appendix B: Bundles and Frameworks
|
||||
@include Bundles.texi
|
||||
|
||||
@c Appendix C: Using the GNUstep make package
|
||||
@include GNUstepMake.texi
|
||||
@c Appendix C: Comparison between Objective-C, Java, and C++
|
||||
@include ObjcAndJavaC++.texi
|
||||
|
||||
@c Appendix D: Comparison between Objective-C and Java
|
||||
@include ObjcAndJava.texi
|
||||
|
||||
@c Appendix E: Programming GNUstep in Java and Guile
|
||||
@c Appendix D: Programming GNUstep in Java and Guile
|
||||
@include JavaAndGuile.texi
|
||||
|
||||
@c Appendix E: GNUstep Compliance to Standards
|
||||
@include Compliance.texi
|
||||
|
||||
|
||||
@unnumbered Concept Index
|
||||
@printindex cp
|
||||
|
||||
@bye
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue