[Openmcl-devel] NSStrings

Gary Byers gb at clozure.com
Wed Mar 3 07:08:22 PST 2004



On Wed, 3 Mar 2004, Paul D. Lathrop wrote:

> I am doing some work with the cocoa/objc bridge (for the Clotho
> project) and I've come across some confusion involving passing a string
> from the lisp to the objc runtime. What I am working on currently is
> implementing a function that will swap the case of the current
> selection. I am able to get the selection and change it's case. I am
> then allocating an nsstring using the following form:
>
> (ccl::%make-nsstring new-string)
>
> new-string is the lispy form of the string I'm trying to send. The
> problem is, when the string reaches the cocoa component I'm sending it
> to, it has one character's worth of garbage appended to it. The lisp
> doesn't see this garbage at all - it registers the nsstring as:
>
> #<NS-CONSTANT-STRING "FOObarBAz" (#x155190)>

That's what the applicable PRINT-OBJECT method returns for that instance
of the ObjC class NS:NS-CONSTANT-STRING (aka "NSConstantString").  The
PRINT-OBJECT method sends the object a "description" message and prints
the (lispified) string that that method returns.  Lisp has no other
idea of what characters are in the string.

(This is in contrast to #@"Foo", which sort of gets interned and
canonicalized: the lisp string gets remembered along with the
NS-CONSTANT-STRING in a little structure, so that the equivalent
NS-CONSTANT-STRING can be recreated after SAVE-APPLICATION.)

An NS-CONSTANT-STRING is something that can be statically created
(it's what the ObjC compiler turns @"Foo" into): it can never be
released, and it and the underlying bytes can be allocated in
read-only storage.

It might or might not be what you want.

>
> whereas, Cocoa gives me:
>
> "FOObarBAz¨"

If you DESCRIBE the value returned by CCL::%MAKE-NSSTRING, you'll
see its instance variables presented as CLOS slots.  They aren't
incredibly interesting:

? (%make-nsstring "abcdefghij")
#<NS-CONSTANT-STRING "abcdefghij" (#x138C10)>
? (describe *)
#<NS-CONSTANT-STRING "abcdefghij" (#x138C10)>
Class: #<OBJC:OBJC-CLASS NS:NS-CONSTANT-STRING (#xA6543EC4)>
Wrapper: #<CLASS-WRAPPER NS:NS-CONSTANT-STRING #x5ACC146>
Instance slots
NS:ISA: #<OBJC:OBJC-CLASS NS:NS-CONSTANT-STRING (#xA6543EC4)>
NS:BYTES: #<A Mac Pointer #x1F4160>
NS:NUM-BYTES: 10

i.e., it's basically just a pointer to some bytes and a count of
those bytes.  It appears that between the time that the constant
string is created and the time that you conclude that Cocoa's
seeing something else something is stepping on the NUM-BYTES slot
of your string.  That shouldn't be possible (via any sort of
advertised means), so something somewhere is scribbling over
memory.

>
> (note the extra char on the end). Am I missing a "proper" way of
> accomplishing this? If not, what am I missing? The only clue I have
> left is that the string I get *from* the objc runtime is:
>
> #<NS-CF-STRING "fooBARbaZ" (#x160B50)>
>
> Which is not what I am sending back. Could this be a problem? If it is,
> how do I allocate the appropriate type of string? If I'm missing
> something obvious, feel free to RTFM me.
>

NS-STRINGs come in several flavors.  Many of them are immutable (and
an NS-CONSTANT-STRING is both immutable and "immortal" in that it's
never deallocated by the runtime.)

Given some kind of NS-STRING, a method like
"stringBy[Appending|Deleting|Padding|...]..." will return a new string
(of some class) that's just like the receiver except for some appending
or deleting or padding ...

There should probably be convenient ways to create other types of
strings from a lisp string (besides CCL::%MAKE-NSSTRING).  It's
not clear that using an NS-CONSTANT-STRING is an issue here, though.

> Thanks,
> Paul Lathrop
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>




More information about the Openmcl-devel mailing list