[Openmcl-devel] object classes and nib files

Dan Knapp dankna at accela.net
Sun Jan 2 15:03:24 PST 2005


> I'm having trouble loading an OBJC class from a nib file.
>
> I have a class HemlockTextView that inherits NSTextView and I do
>
> ? (make-instance 'ns:ns-window-controller :with-window-nib-name 
> #@"test")

   There is an example of how to do this at the end of:

10.2. Instantiating Objective-C Objects
http://www.openmcl.com/Doc/ch10s02.html

   NSWindowController is something of a special case.  It requires the 
:owner
parameter.  The object passed as the :owner should be an allocated but
uninitialized instance of the same class as the one defined in the NIB 
file as
the owner.  It is then initialized to be identical to the saved object.

   Things do appear to work if you leave :owner off, but it's behaviour 
undefined
by Apple.

   This can't be done with (make-instance), because (make-instance) does
both the allocation and the initialization, and it doesn't know about 
the :owner
parameter.  Although there's probably no reason it wouldn't work to call
(allocate-instance) and then (initialize-instance), the way that I know 
works
is to first send the 'alloc message to your class, to obtain an 
uninitialized
instance, and then send the (:init-with-window-nib-name :owner) message
to that instance.

   Here's a working snippet of code from one of my own programs:

(defun init-gui ()
   (with-autorelease-pool
     (unless (objc-object-p *student-list-controller*)
       (let ((it (send (find-class 'student-list-controller) 'alloc)))
	(setq it
	      (send it
		    :init-with-window-nib-path +student-list-nib-path+
		    :owner it))
	(setq *student-list-controller* it)))
     (send *student-list-controller* 'window)
     (send *student-list-controller* :show-window nil)))

   You don't necessarily need the 'window and :show-window messages, of 
course.
You do need the (with-autorelease-pool), unless you've already set up 
an autorelease
pool; if you leave it out, nothing will immediately explode, but you'll 
leak memory.

   Also notice that ObjC initialization methods can return a different 
object than the one
you sent the message too (!), so that setq is necessary.  Lisp will 
ordinarily core-dump
if you forget to do that and then try to print-object the result.

> I'm guessing that something in the cocoa runtime code didn't like my 
> slot definitions, but I don't know what.

   As far as I see, there's nothing wrong with your slot definitions.

> I defined all the slots as Outlets in interface builder, even though 
> event-queue, command-thread and
> needs-display are not :foreign-type. I'm only actually connecting 
> echo-view and master-view so I'm
> not actually trying to assign into those slots, though.

   You shouldn't define event-queue, command-thread, and needs-display 
in the nib if they
are not supposed to hold ObjC objects.  If they are supposed to be 
foreign slots but of no
particular type, you should make them :foreign-type :id.  However, this 
is not the cause of
your current problem.

-- Dan Knapp




More information about the Openmcl-devel mailing list