Re: Passing ids to Distributed Objects
Re: Passing ids to Distributed Objects
- Subject: Re: Passing ids to Distributed Objects
- From: Chris Kane <email@hidden>
- Date: Thu, 5 Dec 2002 11:39:56 -0800
The PictureData object is probably not surviving the archiving and
unarchiving that DO will do (even between threads in the same task),
for any number of reasons.
What you are trying to do here is pass a pointer -- as a value --
between two threads, rather than the data/object pointed to. There is
this ambiguity of meaning, in C, and DO chooses to always interpret
pointers as being pointers to the data/objects which need to be shipped
to the other end of the connection. DO could have chosen to treat
(void *) pointers as flat values and used that as the escape hatch to
send pointer values, but it was implemented long ago to simply disallow
void * pointers, and that hasn't changed. (Probably is easier for
people to figure out what is going wrong to disallow that, rather than
send a flat pointer value for a void *.)
Instead, to disguise the pointers from DO, you need to use the
uintptr_t type as the parameter type (stdint.h is already included for
you) and cast.
Chris Kane
Cocoa Frameworks, Apple
On Wednesday, December 4, 2002, at 12:39 PM, Nicolai wrote:
Don't try to check the code too much. I finally realized that the
code "works". But there is a curious behavior...
Here are the protocols I use to interact between the two threads:
@protocol ThreadMethods // methos for the threads doing some
calculation
- (oneway void)startCalculationWithData:(PictureData *)pPD;
@end
@protocol ThreadControllerMethods // methods of my window controller
how sets up the thread
- (oneway void)setThreadAddress:(id <ThreadMethods>)thread;
- (oneway void)setProgress:(double)status finished:(BOOL)finished;
- (oneway void)setPicture:(NSImage *)pImage;
@end
The thread has its own class and I call the following function by the
window controller
to set it up:
class: ImageProcessor : ThreadBase
+ (void)startThreadForController:(id
<ThreadControllerMethods>)controller
{
NSPort *port1 = [NSPort port];
NSPort *port2 = [NSPort port];
NSArray *ports = [NSArray arrayWithObjects:port2, port1, nil];
NSConnection *connection = [[NSConnection alloc]
initWithReceivePort:port1 sendPort:port2];
[connection setRootObject:controller];
[NSThread detachNewThreadSelector:@selector(_connectWithPorts:)
toTarget:self withObject:ports];
}
+ (void)_connectWithPorts:(NSArray *)ports
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSConnection *connection = [NSConnection
connectionWithReceivePort:[ports objectAtIndex:0]
sendPort:[ports objectAtIndex:1]];
id rootProxy = (id)[connection rootProxy];
ThreadBase *threadBase = [[self alloc] initForParent:rootProxy];
// rootProxy saves into var called parent
[rootProxy setThreadAddress:threadBase]; // send the window
controller the handle
[threadBase release];
[[NSRunLoop currentRunLoop] run];
[pool release];
}
The window controller receives the data correctly:
- (oneway void)setThreadAddress:(id)anObject
{
[anObject setProtocolForProxy:@protocol(ThreadMethods)];
[anObject retain];
[(id)_myThread release];
_myThread = (id <ThreadMethods>)anObject;
}
Now I am able to kick off the calculation:
[_myThread startCalculationWithData: pPictureData]; //pPictureData is
a public member of the window controller object
==>
- (oneway void)startCalculationWithData:(PictureData *)pPD
{
//calculate picture...
//call...
[parent setProgress:y finished:NO]; // parent was saved on
initialization (...initForParent:rootProxy...)
//for several times...
//FINALLY
{
NSImage *pImage;
NSSize size;
size.width = pPD->width;
size.height = pPD->height;
pImage = [[NSImage alloc] initWithSize:size];
[pImage addRepresentation:pBitmapRep];
[parent setPicture:pImage];
[pImage release];
}
}
window controller receives:
- (oneway void)setPicture:(NSImage *)pImage;
{
[imageView setImage:pImage];
[mainWindow display];
}
MY PROBLEM:
First of all startCalculationWithData: doesn't receive a valid pointer.
I've checked the pointers and realized that the pointer I want to pass
has changed when received. I corrected the pointer manually while
debugging
and it works!
The setProgress: calls don't make any problems.
The same problem with the pointer occures when I want to send NSImage
* back.
I also corrected the pointer manually and everything worked.
Any idea what is going wrong?
Regards, Nicolai.
On Mittwoch, Dezember 4, 2002, at 10:35 Uhr, j o a r wrote:
I didn't really understand what you asked here:
Now it is possible to interact between the two object usings
functions declared by protocols.
But whenever I use a function which passes an id like
- (void)setPicture:(NSImage *)pImage; // id acts the same
the id received is invalid. I already made sure that the id
is not released yet.
When you say "invalid", what do you mean?
There are some DO samples on the net, notably the simpleThreads, and
trivialThreads examples from Apple, found here:
http://developer.apple.com/samplecode/Sample_Code/Processes/
TrivialThreads.htm
http://developer.apple.com/samplecode/Sample_Code/Processes/
SimpleThreads.htm
j o a r
On Wednesday, Dec 4, 2002, at 10:06 Europe/Stockholm, Nicolai wrote:
I posted on monday the questestion "Passing ids to Distributed
Objects"
but no one replied. I thought it would be better to look for sample
code.
Maybe my problem (or the text?) is a bit too complicated.
I searched the pages but still didn't found anythings that helps.
Could you think of a sample which uses DOs that passes ids through
the
connection? (both directions)
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.