Re: Distributed Objects, copying thereof
Re: Distributed Objects, copying thereof
- Subject: Re: Distributed Objects, copying thereof
- From: Chris Kane <email@hidden>
- Date: Fri, 9 Jun 2006 11:21:47 -0700
On Jun 8, 2006, at 11:16 AM, Jim Thomason wrote:
To send an object "across the wire" in DO, your object needs to
implement
the NSCoding protocol. As an additional note (that I didn't
encounter in
Apple docs), the object that does the coding in DO (NSPortCoder, I
believe)
does not seem to support keyed coding, so be sure your
encodeWithCoder: and
initWithCoder: methods are old school, and not keyed.
Your object also needs to also implement the following method, in
order to
tell the NSPortCoder to package up and send your actual object
contents, not
just a reference to the object:
- (id)replacementObjectForPortCoder:(NSPortCoder *)encoder
{
if ([encoder isByref]){
return [NSDistantObject proxyWithLocal:self connection:
[encoder
connection]];
} else {
return self;
}
}
Thank you.
While this response is indeed correct and does seem to do what I need
it to do (and, I admit, more simply that my whole "encode to
data/decode myself" nonsense), I've gotta say that it is grade-A
bullplop.
Recall - I'm using NSBezierPaths and NSImages. Those are all that I'm
sending across the wire. Built in apple classes. Merely adding in the
bycopy keyword isn't enough to make my code work, no, I actually do
need to implement replacementObjectForPortCoder:
But, these are apple's classes, not my own. So I'm adding on
categories to NSImage and NSBezierPath to do nothing more than
implement this boilerplate method. And that works just fine.
So why oh why didn't Apple just implement that little boilerplate
version as NSObject's default? As I understand the docs now,
NSObject's always returns a distant proxy and apparently completely
ignores NSPortCoder's byref/bycopy/etc flags, which in turn requires
me to tack on a category to implement a more useful version.
Am I way off base, or does this strike anyone else as being really
silly?
The logic goes something like this: the object returned from
replacementObjectForPortCoder: must conform to the NSCoding protocol,
since that is the object which is going to be encoded for sending to
the other side. NSObject does not implement NSCoding. So logically,
replacementObjectForPortCoder: cannot return self, even when isBycopy
is true.
Conceivably, the original authors could have made the default
definition more complicated, and checked whether self conformed to
NSCoding, and if so, "obeyed" the byref and bycopy keywords. But,
NSCoding itself does not entirely imply that the object is capable of
going over the wire, because an object may have coding behaviors that
are incompatible with wire transfer.
Except I'm now have a different issue. It turns out that it works fine
when I have an image that was created via +imageNamed, but it fails
when I use an image I created programmatically in the code. So this
has lead me to believe that there's something different about my
programmatically created image and one returned by imageNamed, but I
haven't figured out what it could be.
When I read your message yesterday, I was betting you'd run into
trouble with the named images, but it turns out the opposite
happened. :-) NSImages don't always archive their bits, but may
archive a name or a file path instead. Obviously under D.O., when
the other side unarchives a string name and does +imageNamed:, or
unarchives a file path and tries to load the file, it may not exist.
+imageNamed: images with images out of the AppKit bundle are probably
OK, along with images that come out of your app bundle ... if the app
is the thing running on both sides of the D.O. connection. But a
random named image -- you can't expect that to work if the image
archives just the name (or file path for that case), unless the other
side has previously established an image with that name in the name
cache. I'm not sure what "created programmatically in the code"
means, but perhaps that is a way where NSImage doesn't then archive
the bits. You may be better off just sending the data from -
TIFFRepresentation or similar rather than NSImage themselves. I
don't know anything about NSImages really, and I don't know if
there's a way to allocate them such that they'll archive conveniently
for D.O. purposes.
So, the generic NSObject behavior is to send a proxy for everything,
and let each subclass determine it's D.O. transferring behavior. But
of course, many class authors will not consider D.O. and its issues
even though the class may do NSCoding, which makes for another reason
that sending proxies by default is a good default. The D.O.
transferring behavior also includes whether instances will go over
the wire by proxy by default or by copy by default, and possibly obey
the keywords if present, or ignore the keywords.
Chris Kane
Cocoa Frameworks, Apple
Posts on the topic of Distributed Objects by myself are not
to be construed as an endorsement of Distributed Objects.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden