Commits

Bob Ippolito committed fc387e6

update intro

  • Participants
  • Parent commits 6dc74a3
  • Branches pyobjc-ancient

Comments (0)

Files changed (3)

File Doc/Xcode-Templates.html

 PyObjC Xcode Templates</title>
 <meta name="Author" content="Bob Ippolito" />
 <meta name="Contact" content="bob@redivi.com" />
-<title>
-Contents</title>
 </head>
 <body>
 <h2>PyObjC Xcode Templates</h2>
 applications &quot;by hand&quot; using py2app, as described in the
 tutorial.  As of PyObjC 1.3.1, these templates are py2app based,
 so there is no longer a technical reason not to use them.</p>
-<h2>Contents</h2>
+<table border="1" width="80%" align="center"><tbody><tr><td><i><center>Contents</center></i><br />
 <ul>
-<li><a href="#installing" id="id3" name="id3">Installing</a></li>
-<li><a href="#notes" id="id4" name="id4">Notes</a></li>
-<li><a href="#groups" id="id5" name="id5">Groups</a></li>
-<li><a href="#targets" id="id6" name="id6">Targets</a></li>
-<li><a href="#custom-executable" id="id7" name="id7">Custom Executable</a></li>
-<li><a href="#pyobjc-application" id="id8" name="id8">PyObjC Application</a></li>
-<li><a href="#pyobjc-document-based-application" id="id9" name="id9">PyObjC Document Based Application</a></li>
-<li><a href="#pyobjc-mixed-application" id="id10" name="id10">PyObjC Mixed Application</a></li>
+<li><a href="#installing">Installing</a></li>
+<li><a href="#notes">Notes</a></li>
+<li><a href="#groups">Groups</a></li>
+<li><a href="#targets">Targets</a></li>
+<li><a href="#custom-executable">Custom Executable</a></li>
+<li><a href="#pyobjc-application">PyObjC Application</a></li>
+<li><a href="#pyobjc-document-based-application">PyObjC Document Based Application</a></li>
+<li><a href="#pyobjc-mixed-application">PyObjC Mixed Application</a></li>
 </ul>
-<h2><a href="#id3" name="installing">Installing</a></h2>
+</td></tr></tbody></table>
+<h2><a href="#id3">Installing</a></h2>
 <p>If you have installed PyObjC 1.3.1 or later using the installer, then
 the Xcode templates are already installed.</p>
 <p>If you have installed any version of PyObjC prior to 1.3.1, then you
 </pre>
 <p>To install the templates manually, simply copy (or link) them into
 this Project Templates folder.</p>
-<h2><a href="#id4" name="notes">Notes</a></h2>
+<h2><a href="#id4">Notes</a></h2>
 <ul>
 <li>These templates are brand new in PyObjC 1.3.1 and haven't had much
 use yet.  If you think that you have found a bug or would like them to be
 See PyObjC Mixed Application below for more information about using
 plug-ins to integrate non-Python code into your application.</li>
 </ul>
-<h2><a href="#id5" name="groups">Groups</a></h2>
+<h2><a href="#id5">Groups</a></h2>
 <p>The PyObjC Xcode templates use py2app to build applications,
 but they parse the <code><span>.xcode</span></code> project file to determine
 how they should be built, rather than directly in the
 </dl>
 </dd>
 </dl>
-<h2><a href="#id6" name="targets">Targets</a></h2>
+<h2><a href="#id6">Targets</a></h2>
 <dl>
 <dt>Development:</dt>
 <dd><p>This target will use py2app <code><span>--alias</span></code> build mode.  Executables
 project.  The build style has no effect on Python code.</p>
 </dd>
 </dl>
-<h2><a href="#id7" name="custom-executable">Custom Executable</a></h2>
+<h2><a href="#id7">Custom Executable</a></h2>
 <p>The custom executable enables for your built application to be run from Xcode.</p>
 <p>If you rename your main script or fiddle around with your <code><span>Info.plist</span></code>,
 the path to your application may change and this will no longer work.
 <p>Custom executables are specific to a particular user in Xcode, so anything
 you do to this part of the template won't be seen by anyone else unless
 they happen to have the same short user name as you.</p>
-<h2><a href="#id8" name="pyobjc-application">PyObjC Application</a></h2>
+<h2><a href="#id8">PyObjC Application</a></h2>
 <p>This is a simple template that has a window and an application delegate.</p>
-<h2><a href="#id9" name="pyobjc-document-based-application">PyObjC Document Based Application</a></h2>
+<h2><a href="#id9">PyObjC Document Based Application</a></h2>
 <p>This is template demonstrates a Document-based application written in Python.
 It is a simple text editor (like the TinyTinyEdit example).</p>
-<h2><a href="#id10" name="pyobjc-mixed-application">PyObjC Mixed Application</a></h2>
+<h2><a href="#id10">PyObjC Mixed Application</a></h2>
 <p>This template contains both Objective-C and Python code.  The Objective-C code
 is built as a &quot;ProjectNamePlugIn.bundle&quot; plug-in in a separate target.  The plug-in
 is placed in the <code><span>Resources</span></code> directory of your application.  A wrapper script

File Doc/intro.html

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>
 An introduction to PyObjC</title>
-<title>
-Contents</title>
 </head>
 <body>
 <h2>An introduction to PyObjC</h2>
 :contact: pyobjc-dev@lists.sourceforge.net
 :URL: http://pyobjc.sourceforge.net/
 :copyright: 2003-2005 The PyObjC Project -->
-<h2>Contents</h2>
+<table border="1" width="80%" align="center"><tbody><tr><td><i><center>Contents</center></i><br />
 <ul>
-<li><a href="#preface" id="id6" name="id6">Preface</a></li>
-<li><a href="#objective-c-for-pyobjc-users" id="id7" name="id7">Objective-C for PyObjC users</a></li>
-<li><a href="#overview-of-the-bridge" id="id8" name="id8">Overview of the bridge</a><ul>
-<li><a href="#classes" id="id9" name="id9">Classes</a></li>
-<li><a href="#messages-and-functions" id="id10" name="id10">Messages and Functions</a></li>
-<li><a href="#reference-counting" id="id11" name="id11">Reference counting</a></li>
-<li><a href="#protocols" id="id12" name="id12">Protocols</a></li>
-<li><a href="#cocoa-bindings" id="id13" name="id13">Cocoa Bindings</a></li>
-<li><a href="#categories" id="id14" name="id14">Categories</a></li>
+<li><a href="#preface">Preface</a></li>
+<li><a href="#first-steps">First Steps</a><ul>
+<li><a href="#underscores-and-lots-of-them">Underscores, and lots of them</a></li>
+<li><a href="#two-phase-instantiation">Two-phase instantiation</a></li>
+<li><a href="#objective-c-uses-accessors-everywhere">Objective-C uses accessors everywhere</a></li>
 </ul>
 </li>
-<li><a href="#accessing-python-objects-from-objective-c" id="id15" name="id15">Accessing Python objects from Objective-C</a></li>
-<li><a href="#cocoa-for-python-programmers" id="id16" name="id16">Cocoa for Python programmers</a></li>
-<li><a href="#notes-on-specific-tasks" id="id17" name="id17">Notes on specific tasks</a><ul>
-<li><a href="#working-with-threads" id="id18" name="id18">Working with threads</a></li>
-<li><a href="#finalizers" id="id19" name="id19">Finalizers</a></li>
-<li><a href="#copying" id="id20" name="id20">Copying</a></li>
+<li><a href="#objective-c-for-pyobjc-users">Objective-C for PyObjC users</a></li>
+<li><a href="#overview-of-the-bridge">Overview of the bridge</a><ul>
+<li><a href="#classes">Classes</a></li>
+<li><a href="#messages-and-functions">Messages and Functions</a></li>
+<li><a href="#reference-counting">Reference counting</a></li>
+<li><a href="#protocols">Protocols</a></li>
+<li><a href="#cocoa-bindings">Cocoa Bindings</a></li>
+<li><a href="#categories">Categories</a></li>
 </ul>
 </li>
-<li><a href="#building-applications" id="id21" name="id21">Building applications</a><ul>
-<li><a href="#py2app-setup-py" id="id22" name="id22">&quot;py2app&quot; :  setup.py</a></li>
-<li><a href="#ide-approach-xcode" id="id23" name="id23">&quot;IDE approach&quot; : Xcode</a></li>
+<li><a href="#accessing-python-objects-from-objective-c">Accessing Python objects from Objective-C</a></li>
+<li><a href="#cocoa-for-python-programmers">Cocoa for Python programmers</a></li>
+<li><a href="#notes-on-specific-tasks">Notes on specific tasks</a><ul>
+<li><a href="#working-with-threads">Working with threads</a></li>
+<li><a href="#finalizers">Finalizers</a></li>
+<li><a href="#copying">Copying</a></li>
+</ul>
+</li>
+<li><a href="#building-applications">Building applications</a><ul>
+<li><a href="#py2app-setup-py">&quot;py2app&quot; :  setup.py</a></li>
+<li><a href="#ide-approach-xcode">&quot;IDE approach&quot; : Xcode</a></li>
 </ul>
 </li>
 </ul>
-<h2><a href="#id6" name="preface">Preface</a></h2>
+</td></tr></tbody></table>
+<h2><a href="#id6">Preface</a></h2>
 <p>PyObjC is a bridge between Python and Objective-C.  It allows Python 
 scripts to use and extend existing Objective-C class libraries;
 most importantly the <a href="http://developer.apple.com/referencelibrary/API_Fundamentals/Cocoa-api-date.html">Cocoa libraries</a> by <a href="http://www.apple.com/">Apple</a>.</p>
 <p>This document describes how to use Objective-C class libraries from Python
 scripts and how to interpret the documentation of those libraries from the 
 point of view of a Python programmer.</p>
-<h2><a href="#id7" name="objective-c-for-pyobjc-users">Objective-C for PyObjC users</a></h2>
+<h2><a href="#id7">First Steps</a></h2>
+<p>When dealing with the Objective-C runtime, there are certain patterns
+you need to learn when writing Python code.  If you're not already an
+Objective-C programmer, some of them will seem strange or even
+&quot;un-pythonic&quot; at first.  However, you will get used to it, and the way
+that PyObjC works is quite compliant with the <a href="http://www.python.org/peps/pep-0020.html">Zen of Python</a>
+(<code><span>import</span> <span>this</span></code>).  In fact, Ronald is Dutch ;)</p>
+<p>With no further adieu, here are the three most important things you
+<i>must</i> know before embarking on any PyObjC voyage:</p>
+<h3><a href="#id8">Underscores, and lots of them</a></h3>
+<p>Objective-C objects communicate with each other by sending messages.
+The syntax for messages is somewhere in-between Python's positional and
+keyword arguments.  Specificlaly, Objective-C message dispatch uses
+positional arguments, but parts of the message name (called &quot;selector&quot;
+in Objective-C terminology) are interleaved with the arguments.</p>
+<p>An Objective-C message looks like this:</p>
+<pre>
+[someObject doSomething:arg1 withSomethingElse:arg2];
+</pre>
+<p>The selector (message name) for the above snippet is this (note the colons):</p>
+<pre>
+doSomething:withSomethingElse:
+</pre>
+<p>In order to have a lossless and unambiguous translation between Objective-C
+messages and Python methods, the Python method name equivalent is simply
+the selector with colons replaced by underscores.  Since each colon in an
+Objective-C selector is a placeholder for an argument, the number of
+underscores in the PyObjC-ified method name is the number of arguments
+that should be given.</p>
+<p>The PyObjC translation of the above selector is (note the underscores):</p>
+<pre>
+doSomething_withSomethingElse_
+</pre>
+<p>The message dispatch, translated to PyObjC, looks like this:</p>
+<pre>
+someObject.doSomething_withSomethingElse_(arg1, arg2)
+</pre>
+<p><i>Methods that take one argument will have a trailing underscore</i>.</p>
+<p>It may take a little while to get used to, but PyObjC does not ever
+rename selectors.  The trailing underscore will seem strange at first,
+especially for cases like this:</p>
+<pre>
+# note the trailing underscore
+someObject.setValue_(aValue)
+</pre>
+<p>There are a few additional rules regarding message dispatch, see the 
+<a href="#overview-of-the-bridge">Overview of the bridge</a> for the complete rundown.</p>
+<h3><a href="#id9">Two-phase instantiation</a></h3>
+<p>Objective-C, being a low-level runtime, separates the two concepts required
+to instantiate an object.</p>
+<dl>
+<dt>allocation:</dt>
+<dd><p>Reserve a chunk of memory large enough to hold the new object, and make
+sure that all of its declared instance variables are set to &quot;zero&quot;
+(this means nil pointers to objects, 0 for integers, etc.).</p>
+</dd>
+<dt>initialization:</dt>
+<dd><p>Fill in the blank slate allocated by the allocation phase.</p>
+</dd>
+</dl>
+<p>In Objective-C, the convention is for allocation to be performed by a class
+method called <code><span>alloc</span></code>, and initialization is done with method
+<i>beginning with</i> the word <code><span>init</span></code>.  For example, here is the syntax for
+instantiating an <code><span>NSObject</span></code>:</p>
+<pre>
+myObject = NSObject.alloc().init()
+</pre>
+<p>And here is an example for creating an <code><span>NSData</span></code> instance given a few bytes:</p>
+<pre>
+myData = NSData.alloc().initWithBytes_length_('the bytes', 9)
+</pre>
+<p>You must also follow this convention when subclassing Objective-C classes.
+When initializing, an object must always (directly or indirectly) call the
+designated initializer of its <code><span>super</span></code>.  The designated initializer is the
+&quot;most basic&quot; initializer through which all initialization eventually ends up.
+The designated initializer for <code><span>NSObject</span></code> is <code><span>init</span></code>.  To find the
+designated initializer for other classes, consult the documentation for that
+class.  Here is an example of an <code><span>NSObject</span></code> subclass with a customized
+initialization phase:</p>
+<pre>
+class MyClass(NSObject):
+
+    def init(self):
+        &quot;&quot;&quot;
+        Designated initializer for MyClass
+        &quot;&quot;&quot;
+        # ALWAYS call the super's designated initializer.
+        # Also, make sure to re-bind &quot;self&quot; just in case it
+        # returns something else!
+        self = super(MyClass, self).init()
+
+        self.myVariable = 10
+
+        # Unlike Python's __init__, initializers MUST return self,
+        # because they are allowed to return any object!
+        return self
+
+class MyOtherClass(MyClass):
+
+    def initWithOtherVariable_(self, otherVariable):
+        &quot;&quot;&quot;
+        Designated initializer for MyOtherClass
+        &quot;&quot;&quot;
+        self = super(MyOtherClass, self).init()
+        self.otherVariable = otherVariable
+        return self
+
+myInstance = MyClass.alloc().init()
+myOtherInstance = MyOtherClass.alloc().initWithOtherVariable_(20)
+</pre>
+<p>Many Objective-C classes provide class methods that perform two-phase
+instantiation for you in one step.  Several examples of this are:</p>
+<pre>
+# This is equivalent to:
+#
+#   myObject = NSObject.alloc().init()
+#
+myObject = NSObject.new()
+
+# This is equivalent to:
+#
+#   myDict = NSDictionary.alloc().init()
+#
+myDict = NSDictionary.dictionary()
+
+# This is equivalent to:
+#
+#   myString = NSString.alloc().initWithString_(u'my string')
+#
+myString = NSString.stringWithString_(u'my string')
+</pre>
+<h3><a href="#id10">Objective-C uses accessors everywhere</a></h3>
+<p>Unlike Python, Objective-C convention says to use accessors rather than
+directly accessing instance variables of other objects.  This means
+that in order to access an instance variable <code><span>value</span></code> of an object
+<code><span>valueContainer</span></code> you will have to use the following syntax:</p>
+<pre>
+# Getting
+#
+# notice the method call
+#
+myValue = valueContainer.value()
+
+# Setting
+#
+# notice the naming convention and trailing underscore
+#
+valueContainer.setValue_(myNewValue)
+</pre>
+<p>When writing your own classes from Python, this is a bit harder since
+Python only has one namespace for all attributes, even methods.  If you
+choose to implement accessors from Python, then you will have to name
+the instance variable something else:</p>
+<pre>
+class MyValueHolder(NSObject):
+
+    def initWithValue_(self, value):
+        self = super(MyValueHolder, self).init()
+        # It's recommended not to use typical Python convention here,
+        # as instance variables prefixed with underscores are reserved
+        # by the Objective-C runtime.  It still works if you use
+        # underscores, however.
+        self.ivar_value = value
+        return self
+
+    def value(self):
+        return self.ivar_value
+
+    def setValue_(self, value):
+        self.ivar_value = value
+</pre>
+<p>It's also possible to use <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/">Key-Value Coding</a> in some cases, which eliminates
+the need for writing most accessors, but only in scenarios where the rest of
+the code is using it.</p>
+<h2><a href="#id11">Objective-C for PyObjC users</a></h2>
 <p>It is recommended that you take the time to understand a little bit about
 Objective-C before jumping into PyObjC development.  The class libraries
 that you will be using from Cocoa are not documented in Python, and their
 <ul>
 <li><a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html">The Objective-C Programming Language</a> at <a href="http://www.apple.com/">Apple</a>.</li>
 </ul>
-<h2><a href="#id8" name="overview-of-the-bridge">Overview of the bridge</a></h2>
-<h3><a href="#id9" name="classes">Classes</a></h3>
+<h2><a href="#id12">Overview of the bridge</a></h2>
+<h3><a href="#id13">Classes</a></h3>
 <p>Objective-C classes are visible as (new-style) Python classes and can be 
 subclassed just like normal Python classes.  All the usual introspection
 mechanisms work as well, as do <code><span>__slots__</span></code> and descriptors.  The major 
 initializer (typically starts with <code><span>init</span></code>).  Some classes have class methods
 which perform this behind the scenes, especially classes that create cached,
 immutable, or singleton instances.</p>
-<h3><a href="#id10" name="messages-and-functions">Messages and Functions</a></h3>
+<h3><a href="#id14">Messages and Functions</a></h3>
 <p>Objective-C methods are bridged to Python methods.  Because Objective-C
 message dispatch syntax can not be translated directly to Python, a few
 simple translations must take place.  The rules for these translations are:</p>
         def someMethod_(self, arg):
                 pass
 </pre>
-<h3><a href="#id11" name="reference-counting">Reference counting</a></h3>
+<h3><a href="#id15">Reference counting</a></h3>
 <p>The <a href="http://developer.apple.com/referencelibrary/API_Fundamentals/Cocoa-api-date.html">Cocoa libraries</a>, and most (if not all) other class libraries for 
 Objective-C use explicit reference counting to manage memory.  The methods
 <code><span>retain</span></code>, <code><span>release</span></code> and <code><span>autorelease</span></code> are used to manage these 
 subclasses of <code><span>NSObject</span></code> to represent the nodes in the outline view.</p>
 <p>Another gotcha is that <code><span>obj.setDelegate_()</span></code> often does <i>not</i> retain the
 delegate, so a reference should be maintained elsewhere.</p>
-<h3><a href="#id12" name="protocols">Protocols</a></h3>
+<h3><a href="#id16">Protocols</a></h3>
 <p>Cocoa defines a number of formal and informal protocols that specify methods
 that should be implemented by a class if it is to be used in a specific role,
 such as the data source for an <code><span>NSTableView</span></code>.</p>
 objects to add the right method signatures to methods, and to warn about
 classes that partially implement a protocol.</p>
 <p>See <a href="protocols.html">PyObjC protocol support</a> for more information.</p>
-<h3><a href="#id13" name="cocoa-bindings">Cocoa Bindings</a></h3>
+<h3><a href="#id17">Cocoa Bindings</a></h3>
 <p>In Mac OS X 10.3 Apple introduced <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/">Cocoa Bindings</a>, a method to make it easier
 to create and use <i>Controller</i> objects using <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueObserving/">Key-Value Observing</a> and
 <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/">Key-Value Coding</a>.  In order to create accessors compatible with this, you
 must use <code><span>objc.accessor</span></code> to create an appropriate selector descriptor.</p>
-<h3><a href="#id14" name="categories">Categories</a></h3>
+<h3><a href="#id18">Categories</a></h3>
 <p>Objective-C has a mechanism for modularize a class definition, it is possible
 to add methods to an existing class in a separate compilation unit and even
 a separate library.  This mechanism is named categories and is used to enhance
 <p>To make it clear that <code><span>objc.Category</span></code> performs a special task the name in
 the class definition must be the same as the <code><span>__name__</span></code> of the argument
 to <code><span>objc.Category</span></code>.</p>
-<h2><a href="#id15" name="accessing-python-objects-from-objective-c">Accessing Python objects from Objective-C</a></h2>
+<h2><a href="#id19">Accessing Python objects from Objective-C</a></h2>
 <p>All Python objects can be accessed from Objective-C through proxy objects.
 Whenever a Python object crosses the line from Python to Objective-C a proxy
 object is created (of class <code><span>OC_PythonObject</span></code>, a subclass of <code><span>NSProxy</span></code>).
 </ul>
 <p>These special cases allow for more transparent bridging between Python and
 Objective-C.</p>
-<h2><a href="#id16" name="cocoa-for-python-programmers">Cocoa for Python programmers</a></h2>
+<h2><a href="#id20">Cocoa for Python programmers</a></h2>
 <p>Cocoa frameworks are mapped onto Python packages with the same name; that is
 the classes, constants and functions from the AppKit framework are available
 after you import <code><span>AppKit</span></code> in your Python script.</p>
 <li><a href="http://www.stepwise.com/">stepwise.com</a></li>
 <li>Your local bookstore or library</li>
 </ul>
-<h2><a href="#id17" name="notes-on-specific-tasks">Notes on specific tasks</a></h2>
-<h3><a href="#id18" name="working-with-threads">Working with threads</a></h3>
+<h2><a href="#id21">Notes on specific tasks</a></h2>
+<h3><a href="#id22">Working with threads</a></h3>
 <p>Most of Cocoa, and thus PyObjC, requires an <code><span>NSAutoreleasePool</span></code> in order to function
 properly.  PyObjC does this automatically on the first thread it is imported from,
 but other threads will require explicit <code><span>NSAutoreleasePool</span></code> management.  The following
 in the body of the loop in order to optimize memory usage.  For example, <code><span>NSRunLoop</span></code>
 will be create a new <code><span>NSAutoreleasePool</span></code> at the beginning of each run loop iteration
 and release it at the end.</p>
-<h3><a href="#id19" name="finalizers">Finalizers</a></h3>
+<h3><a href="#id23">Finalizers</a></h3>
 <p>In normal Python, there are two methods for writing finalizers: implementing
 <code><span>__del__</span></code>, and using <code><span>weakref.ref</span></code> callbacks.  Generally, <code><span>__del___</span></code> is
 discouraged as it does not allow the object to participate in cyclic garbage
 object.  It is probably technically possible to do, but tricky, so it
 may eventually be implemented in a future version of PyObjC (especially
 if a future Objective-C runtime supports it).</p>
-<h3><a href="#id20" name="copying">Copying</a></h3>
+<h3><a href="#id24">Copying</a></h3>
 <p>It is possible for a Python subclass of an Objective-C class to implement
 the <code><span>NSCopying</span></code> protocol.  Some care must be taken when the superclass
 already implements the protocol.</p>
 <p>NOTE2: <code><span>SomeClass.copyWithZone_</span></code> should not be implemented unless a
 superclass already implements <code><span>copyWithZone:</span></code>, or else the behavior
 will be undefined (memory corruption, crashes, etc.).</p>
-<h2><a href="#id21" name="building-applications">Building applications</a></h2>
+<h2><a href="#id25">Building applications</a></h2>
 <p>There are two different recommended ways to build applications with PyObjC.</p>
-<h3><a href="#id22" name="py2app-setup-py">&quot;py2app&quot; :  setup.py</a></h3>
+<h3><a href="#id26">&quot;py2app&quot; :  setup.py</a></h3>
 <p>The PyObjC installer includes a copy of the <code><span>py2app</span></code> package.  This package
 offers a way to build distutils scripts for building (standalone)
 applications and plugin bundles.</p>
 <pre>
 python setup.py py2app --help
 </pre>
-<h3><a href="#id23" name="ide-approach-xcode">&quot;IDE approach&quot; : Xcode</a></h3>
+<h3><a href="#id27">&quot;IDE approach&quot; : Xcode</a></h3>
 <p>PyObjC includes a number of Xcode templates that can be used to 
 develop applications, using the same underlying functionality that
 is in py2app.  These templates are used like any other Xcode template,

File Doc/intro.txt

 
 .. _`Apple`: http://www.apple.com/
 
+First Steps
+-----------
+
+When dealing with the Objective-C runtime, there are certain patterns
+you need to learn when writing Python code.  If you're not already an
+Objective-C programmer, some of them will seem strange or even
+"un-pythonic" at first.  However, you will get used to it, and the way
+that PyObjC works is quite compliant with the `Zen of Python`_
+(``import this``).  In fact, Ronald is Dutch ;)
+
+.. _`Zen of Python`: http://www.python.org/peps/pep-0020.html
+
+With no further adieu, here are the three most important things you
+*must* know before embarking on any PyObjC voyage:
+
+Underscores, and lots of them
+.............................
+
+Objective-C objects communicate with each other by sending messages.
+The syntax for messages is somewhere in-between Python's positional and
+keyword arguments.  Specificlaly, Objective-C message dispatch uses
+positional arguments, but parts of the message name (called "selector"
+in Objective-C terminology) are interleaved with the arguments.
+
+An Objective-C message looks like this::
+
+    [someObject doSomething:arg1 withSomethingElse:arg2];
+
+The selector (message name) for the above snippet is this (note the colons)::
+
+    doSomething:withSomethingElse:
+
+In order to have a lossless and unambiguous translation between Objective-C
+messages and Python methods, the Python method name equivalent is simply
+the selector with colons replaced by underscores.  Since each colon in an
+Objective-C selector is a placeholder for an argument, the number of
+underscores in the PyObjC-ified method name is the number of arguments
+that should be given.
+
+The PyObjC translation of the above selector is (note the underscores)::
+
+    doSomething_withSomethingElse_
+
+The message dispatch, translated to PyObjC, looks like this::
+
+    someObject.doSomething_withSomethingElse_(arg1, arg2)
+
+*Methods that take one argument will have a trailing underscore*.
+
+It may take a little while to get used to, but PyObjC does not ever
+rename selectors.  The trailing underscore will seem strange at first,
+especially for cases like this::
+
+    # note the trailing underscore
+    someObject.setValue_(aValue)
+
+There are a few additional rules regarding message dispatch, see the 
+`Overview of the bridge`_ for the complete rundown.
+
+Two-phase instantiation
+.......................
+
+Objective-C, being a low-level runtime, separates the two concepts required
+to instantiate an object.
+
+allocation:
+    Reserve a chunk of memory large enough to hold the new object, and make
+    sure that all of its declared instance variables are set to "zero"
+    (this means nil pointers to objects, 0 for integers, etc.).
+
+initialization:
+    Fill in the blank slate allocated by the allocation phase.
+
+In Objective-C, the convention is for allocation to be performed by a class
+method called ``alloc``, and initialization is done with method
+*beginning with* the word ``init``.  For example, here is the syntax for
+instantiating an ``NSObject``::
+
+    myObject = NSObject.alloc().init()
+
+And here is an example for creating an ``NSData`` instance given a few bytes::
+
+    myData = NSData.alloc().initWithBytes_length_('the bytes', 9)
+
+You must also follow this convention when subclassing Objective-C classes.
+When initializing, an object must always (directly or indirectly) call the
+designated initializer of its ``super``.  The designated initializer is the
+"most basic" initializer through which all initialization eventually ends up.
+The designated initializer for ``NSObject`` is ``init``.  To find the
+designated initializer for other classes, consult the documentation for that
+class.  Here is an example of an ``NSObject`` subclass with a customized
+initialization phase::
+
+    class MyClass(NSObject):
+
+        def init(self):
+            """
+            Designated initializer for MyClass
+            """
+            # ALWAYS call the super's designated initializer.
+            # Also, make sure to re-bind "self" just in case it
+            # returns something else!
+            self = super(MyClass, self).init()
+
+            self.myVariable = 10
+
+            # Unlike Python's __init__, initializers MUST return self,
+            # because they are allowed to return any object!
+            return self
+
+    class MyOtherClass(MyClass):
+
+        def initWithOtherVariable_(self, otherVariable):
+            """
+            Designated initializer for MyOtherClass
+            """
+            self = super(MyOtherClass, self).init()
+            self.otherVariable = otherVariable
+            return self
+
+    myInstance = MyClass.alloc().init()
+    myOtherInstance = MyOtherClass.alloc().initWithOtherVariable_(20)
+
+Many Objective-C classes provide class methods that perform two-phase
+instantiation for you in one step.  Several examples of this are::
+
+    # This is equivalent to:
+    #
+    #   myObject = NSObject.alloc().init()
+    #
+    myObject = NSObject.new()
+
+    # This is equivalent to:
+    #
+    #   myDict = NSDictionary.alloc().init()
+    #
+    myDict = NSDictionary.dictionary()
+
+    # This is equivalent to:
+    #
+    #   myString = NSString.alloc().initWithString_(u'my string')
+    #
+    myString = NSString.stringWithString_(u'my string')
+
+Objective-C uses accessors everywhere
+.....................................
+
+Unlike Python, Objective-C convention says to use accessors rather than
+directly accessing instance variables of other objects.  This means
+that in order to access an instance variable ``value`` of an object
+``valueContainer`` you will have to use the following syntax::
+
+    # Getting
+    #
+    # notice the method call
+    #
+    myValue = valueContainer.value()
+
+    # Setting
+    #
+    # notice the naming convention and trailing underscore
+    #
+    valueContainer.setValue_(myNewValue)
+
+When writing your own classes from Python, this is a bit harder since
+Python only has one namespace for all attributes, even methods.  If you
+choose to implement accessors from Python, then you will have to name
+the instance variable something else::
+
+    class MyValueHolder(NSObject):
+
+        def initWithValue_(self, value):
+            self = super(MyValueHolder, self).init()
+            # It's recommended not to use typical Python convention here,
+            # as instance variables prefixed with underscores are reserved
+            # by the Objective-C runtime.  It still works if you use
+            # underscores, however.
+            self.ivar_value = value
+            return self
+
+        def value(self):
+            return self.ivar_value
+
+        def setValue_(self, value):
+            self.ivar_value = value
+
+It's also possible to use `Key-Value Coding`_ in some cases, which eliminates
+the need for writing most accessors, but only in scenarios where the rest of
+the code is using it.
+
 Objective-C for PyObjC users
 ----------------------------