    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: An Introduction to Objective-C</title>
        <link>https://members.accu.org/index.php/journals/704</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">CVu Journal Vol 16, #6 - Dec 2004 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c99/">166</a>
                    (12)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c99-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c99+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;An Introduction to Objective-C</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 December 2004 13:16:08 +00:00 or Fri, 03 December 2004 13:16:08 +00:00</p>
<p><strong>Summary:</strong>&nbsp;<p>Part 3 - An Example Using Foundation</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e22" id="d0e22"></a></h2>
</div>
<p>The best way to get the feel of a programming language is to
have a look at actual code. This demonstration program I've written
consists of three Objective-C source files:</p>
<p>Listing 1 shows <tt class="filename">main.m</tt>, which reads
file names from the command line and prints the unique lexical
tokens found in each file. Tokens are strings of printable
characters separated by whitespace and punctuation marks.</p>
<p>Listing 2 shows <tt class="filename">StringTokenizer.h</tt>,
which declares the public interface of the class <tt class=
"classname">StringTokenizer</tt>. Private methods, being part of
the implementation, typically have no place in this file.</p>
<p>Listing 3 shows <tt class="filename">StringTokenizer.m</tt>,
which contains the implementation of the <tt class=
"classname">StringTokenizer</tt> class.</p>
<p><span class="bold"><b>Listing 1:</b></span> <tt class=
"filename">main.m</tt></p>
<pre class="programlisting">
#import &lt;Foundation/Foundation.h&gt;
#import &quot;StringTokenizer.h&quot;

// Prints unique tokens found in files
// supplied as arguments.

int main(int argc, const char *argv[]) {

  // Create a pool of items to be garbage-collected
  NSAutoreleasePool *pool
                 = [[NSAutoreleasePool alloc] init];
  if(argc &gt; 1) {
    int i;
    for(i = 1; i &lt; argc; ++i) {
      // Read contents of file into string
      NSString *path
             = [NSString stringWithCString:argv[i]];
      NSString *myString
         = [NSString stringWithContentsOfFile:path];
      if(myString == nil) {
        fprintf(stderr, &quot;File %s not found\n&quot;,
                [path cString]);
        // The system will clean up anyway when we
        // exit,  but we do this for form's sake
        [pool release];
        return 1;
      }

      // Create our tokenizer
      StringTokenizer *tokenizer
            = [[[StringTokenizer alloc]
                initWithString:myString
                andDelimiters:@&quot; ,.!?;:\t\r\n&quot;]
               autorelease];

      // Create a set with room for 100 items to
      // hold unique tokens
      NSMutableSet *theSet
               = [NSMutableSet setWithCapacity:100];

      // Get the first token
      NSString *token = [tokenizer nextToken];
      while(token != nil) {
        // This will fail if there is an identical
        // token there already
        [theSet addObject:token];
        // Get more tokens
        token = [tokenizer nextToken];
      }

      // Print out unique tokens in the set in case-
      // insensitive alphabetical order
      NSArray *tokens = [[theSet allObjects]
                 sortedArrayUsingSelector:@selector(
                 caseInsensitiveCompare:)];

      printf(&quot;Unique tokens in %s:\n&quot;,
             [path cString]);

      int j;
      for(j = 0; j &lt; [theSet count]; ++j)
        printf(&quot;\t%d %s\n&quot;, j+1,
               [[tokens objectAtIndex:j] cString]);
    }
  }
  else
    fprintf(stderr,
       &quot;Usage: StringTokenizer file1 file2 ...\n&quot;);

  // Trigger autorelease of allocated memory
  [pool release];
  return 0;
}
</pre>
<p><span class="bold"><b>Listing 2:</b></span> <tt class=
"filename">StringTokenizer.h</tt></p>
<pre class="programlisting">
// Minimal tokenizer class, useful for
// demonstration purposes only
#import &lt;Foundation/Foundation.h&gt;
@interface StringTokenizer : NSObject {
  NSString *data;
  NSCharacterSet *delimiters;
  size_t position, dataSize;
}

// Default initializer - object contains no data
// and delimiters string set to space, tab, newline
// and return
- (id)init;

// Initialise object with data string;
// delimiters string is set to space, tab
// newline and return.
- (id)initWithString:(const NSString *)aString;

// Initialise object with data string to tokenise
// and a set of delimiters to ignore
- (id)initWithString:(const NSString *)aString andDelimiters:(NSString *)delims;

// Assign the object a new data string to
// tokenise
- (void)setData:(const NSString *)aString;

// Assign the object a new set of delimiters to work
// with
- (void)setDelimiters:(NSString *)delims;

// Return the next token from the data string or nil
// if none exists
- (NSString *)nextToken;

@end
</pre>
<p><span class="bold"><b>Listing 3:</b></span> <tt class=
"filename">StringTokenizer.m</tt></p>
<pre class="programlisting">
#import &quot;StringTokenizer.h&quot;

// Default delimiters are whitespace
#define DEFAULT_DELIMITERS @&quot; \t\n\r&quot;

// Create a category to forward-declare
// private method in order to avoid
// compiler warnings about undeclared methods.
@interface StringTokenizer (Private)
- (void)skipDelimiters;
@end

@implementation StringTokenizer

- (id)init
{
  return [self initWithString:nil
          andDelimiters:DEFAULT_DELIMITERS];
}

- (id)initWithString:(const NSString *)aString
{
  return [self initWithString:aString
          andDelimiters:DEFAULT_DELIMITERS];
}

// This is the designated initialiser, which
// is called by all the other initialisers and
// does all the work
- (id)initWithString:(const NSString *)aString
      andDelimiters:(NSString *)delims
{
  if(self = [super init]) {
    position = 0;
    data = [aString retain];

    // Cache length of data string
    dataSize = [data length];
    delimiters = [[NSCharacterSet
          characterSetWithCharactersInString:delims]
          retain];
  }
  return self;
}

- (void)setData:(const NSString *)aString
{
  if(aString != data) {
    [data release];
    position = 0; // We are starting from scratch
    data = [aString retain];
    dataSize = [data length];
  }
}

- (void)setDelimiters:(NSString *)delims
{
  [delimiters release];
  delimiters = [[NSCharacterSet
        characterSetWithCharactersInString:delims]
        retain];
}

- (NSString *)nextToken
{
  if(data == nil || position &gt;= dataSize)
    return nil;

  [self skipDelimiters];
  if(position &gt;= dataSize)
    return nil;

  size_t oldPosition = position;
                      // Save current position

  BOOL nonDelim = YES;
                    // Assume that the next
                    // character is a non-delimiter

  while(position &lt; dataSize &amp;&amp; nonDelim) {
    // Test for a match in the delimiter string of
    // the character at the current position in the
    // data string; if no match is found, increment
    // position and proceed.
    if(![delimiters characterIsMember:
         [data characterAtIndex:position]])
      position++;
    else
      nonDelim = NO;
  }

  // Create a string containing the token and return
  // it. Type NSRange is a struct containing two
  // members: location and length
  NSRange range = {oldPosition, position-oldPosition};
  return [data substringWithRange:range];
}

- (void)skipDelimiters
{
  BOOL nonDelim = NO;
          // Non-delimiter character not yet found

  while (position &lt; dataSize &amp;&amp; !nonDelim) {
    // Test for a match in the delimter string of
    // the character at the current position in the
    // data string; if a match is found, increment
    // position and proceed.
    if([delimiters characterIsMember:
        [data characterAtIndex:position]])
      position++;
    else
      nonDelim = YES;
  }
}

// Invoked automatically when object is released 
- (void)dealloc
{
  // Release memory allocated for our instance
  // variables
  [data release];
  [delimiters release];
  [super dealloc];
}

@end
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e71" id="d0e71"></a>Notes</h2>
</div>
<p>The preprocessor directive <tt class="literal">#import</tt> is
generally used in Objective-C; it differs from <tt class=
"literal">#include</tt> in that it ensures that a header file is
included only once even if it does not contain guard macros.</p>
<p>Foundation's memory management involves semi-automated reference
counting. Pointers to all the objects allocated in the main
function will be added to the autorelease pool, and when this pool
is released, the method <tt class="methodname">-dealloc</tt> is
called on all the objects before the memory they occupy is
freed.</p>
<p>Memory allocation for objects is usually provided by the method
<tt class="methodname">+alloc</tt> in the root class, <tt class=
"classname">NSObject</tt>. -retain increases the reference count by
one, while <tt class="methodname">-release</tt> decrements it.
<tt class="methodname">-autorelease</tt> adds the receiver to the
autorelease pool.</p>
<p><tt class="classname">NSString</tt> is Foundation's basic
string-handling class. <tt class="classname">NSString</tt> objects
hold Unicode strings that cannot be changed once created; objects
of its subclass <tt class="classname">NSMutableString</tt> allow
their contents to be edited.</p>
<p><tt class="classname">StringTokenizer</tt> is a class I have
written to extract tokens from a string. It has limited
functionality but is sufficient for the purposes of this demo.
Tokens are extracted by calling <tt class=
"methodname">nextToken</tt> repeatedly until nil is returned. An
instance of <tt class="classname">StringTokenizer</tt> is created
by calling the class method alloc to allocate storage for the
object and then the object is initialised by the instance method
<tt class="methodname">initWithString:andDelimiter:</tt>, which
does the same kind of work as a constructor in C++ and Java.</p>
<p>The Objective-C keyword <tt class="literal">nil</tt> refers to a
null object. It differs from the macro NULL in that it is perfectly
legal and safe to send messages to nil.</p>
<p><tt class="classname">NSMutableSet</tt> is a subclass of
<tt class="classname">NSSet</tt>, from which it differs by allowing
objects to be inserted and deleted after it has been initialised.
Instances of <tt class="classname">NSSet</tt> and <tt class=
"classname">NSMutableSet</tt> are unordered collections of values,
where each value occurs at most once.</p>
<p>Objects of class <tt class="classname">NSArray</tt> are
immutable ordered collections of objects. The line:</p>
<pre class="programlisting">
NSArray *tokens = [[theSet allObjects]
                sortedArrayUsingSelector:
                @selector(caseInsensitiveCompare:)];
</pre>
<p>deserves some comment. First the message <tt class=
"methodname">allObjects</tt> sent to the set causes it to return an
<tt class="classname">NSArray</tt> of its contents in arbitrary
order; this <tt class="classname">NSArray</tt> object then receives
the message <tt class="methodname">sortedArrayUsingSelector:</tt>
with the selector of <tt class="classname">NSString</tt>'s
<tt class="methodname">caseInsensitiveCompare:</tt> method as
argument. (The compiler directive <tt class=
"literal">@selector</tt> turns a method name into a selector.) The
<tt class="classname">NSArray</tt> object's method <tt class=
"methodname">sortedArrayUsingSelector</tt> then returns a new copy
of itself with the <tt class="classname">NSString</tt> objects in
case-insenstitive ascending collating order.</p>
<p>The <tt class="classname">StringTokenizer</tt> class contains an
instance variable called delimiters of type <tt class=
"classname">NSCharacterSet</tt>. Its method, <tt class=
"methodname">characterIsMember</tt>: is called for each character
of the string in turn; if the character is found in the delimiters
character set, it is skipped, and any non-delimiter or unbroken
sequence thereof is recognised as a token and returned.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
