Re: NSThread question - DO to make it sing
Re: NSThread question - DO to make it sing
- Subject: Re: NSThread question - DO to make it sing
- From: "Dennis C. De Mars" <email@hidden>
- Date: Thu, 12 Jul 2001 00:58:27 -0700
on 7/11/01 10:39 AM, Candide Kemmler at email@hidden wrote:
>
>
Le mercredi 11 juillet 2001, ` 06:57, Dennis C. De Mars a icrit :
>
>
> on 7/11/01 8:47 AM, Candide Kemmler at email@hidden wrote:
>
>
>
>> Le mardi 10 juillet 2001, ` 06:54, Miguel Morales a icrit :
>
>>>
>
>>> However, this would spawn a thread, but the main thread would wait for
>
>>> the secondary thread to finish before continuing, and not give you any
>
>>> of the functionality you want of the main thread plugging along. This
>
>>> is where DO comes in. I will assume that there is a main object that
>
>>> is running in a run loop, and that when the button gets pushed the
>
>>> method -(void)button:(NSData *)data is called, and that there is
>
>>> another method in the object that draws to the screen (also in the
>
>>> main
>
>>> object) called -(oneway void)display:(bycopy NSData *)data.
>
>>
>
>> Great ! I've read the chapter on DO in "Object-Oriented Programming and
>
>> the Objective-C Language" and I'm enthusiast about learning more on DO
>
>> in OC. For a java-fan like me, it's like doing RMI and multi-threading
>
>> at once ! However I find it a little odd to be forced to do rmi (or
>
>> rpc,
>
>> or whatever-you-name-it) just to do multi-threading.
>
>>
>
>> You said that the code snippet you give "would spawn a thread, but the
>
>> main thread would wait for the secondary thread to finish before
>
>> continuing" !!!!! That's the whole point of doing threads !
>
>>
>
>> Consider the following bit of java code:
>
>>
>
>> public void actionPerformed ( ActionEvent evt ) {
>
>> if ( evt.getSource () == myButton ) {
>
>> ( new Thread () {
>
>> public void run () {
>
>> renderMyImage ();
>
>> }
>
>> } ).start ();
>
>> }
>
>> }
>
>>
>
>> Isn't there a way as simple as this do achieve the same effect in
>
>> Objective-C/Cocoa ?
>
>
>
> If your "renderMyImage" routine used any Swing classes to do its
>
> rendering,
>
> you'd have a problem with this code too, because Swing is not
>
> thread-safe
>
> either; you are supposed to do all drawing in the main thread there too.
>
>
>
> I think this is true of pretty much any GUI system of any complexity
>
> ever
>
> devised -- you simply have to defer drawing to the main thread.
>
>
>
> - Dennis D.
>
>
consider the following renderMyImage implementation (not tested):
>
>
java.awt.Image renderMyImage () {
>
java.awt.image.BufferedImage image = new
>
java.awt.image.BufferedImage ( 450, 345, BufferedImage.TYPE_INT_ARGB );
>
Graphics2D g2d = image.createGraphics ();
>
g2d.setColor ( Color.red );
>
g2d.fillRect ( 0, 0, 450, 345 );
>
return image;
>
}
>
>
There's no Swing code involved, and now I have an image I can send to a
>
Swing component to draw it with something like
>
>
g.drawImage ( image, 0, 0, this );
>
>
Simple enough, huh ? And that's exactly what I'd like to do in OC/Cocoa.
Well, if you are talking about rendering an image offscreen in a secondary
thread, but only displaying it onscreen in the main thread, I think you
should be able to do that safely in Cocoa...if you look at:
http://developer.apple.com/techpubs/macosx/ReleaseNotes/ThreadSupport.html
...they have a discussion of modifying NSViews in threads. Although I could
have used a more thorough discussion than Apple provides in this release
note, they seem to imply that the only thing to really avoid is doing actual
on-screen updates anywhere but in the main thread, which is understandable
since otherwise the main thread and another thread could be trying to modify
the same on-screen pixels at the same time. But, if you have a thread
drawing to an off-screen image that is owned by that thread, that should
work. At least that's the impression I get, I haven't done too much of this
myself.
The original code you posted is doing its work offscreen, so I think it
should be all right. Some of the errors you were getting might be due to the
fact that the line:
[ NSThread detachNewThreadSelector:@selector(renderImage)
toTarget:mapRenderer withObject:data ];
should have been
[ NSThread detachNewThreadSelector:@selector(renderImage:)
toTarget:mapRenderer withObject:data ];
The colon is part of the selector name, so I think that's why you got
several messages about an unrecognized selector.
- Dennis D.