Distributed Objects bycopy oder byref default?

  • Distributed Objects bycopy oder byref default?

    Hi Experten,

    ich habe mal eine Frage. Ich konnte in den Dokus von Apple nicht finden was eigentlich das Default-Verhalten bei Rückgabewerten mit DO ist.

    Hier ein Beispiel:

    Quellcode

    1. @protocol DictReceiver
    2. - (bycopy NSDictionary*)dictionary;
    3. @end
    4. @interface Server : NSObject<DictReceiver> {
    5. }
    6. - (NSDictionary*)dictionary;
    7. @end


    Das bycopy ist (zu mindest unter Leopard) überflüssig weil es auch ohne 'bycopy' eine Kopie von NSDictionary erstellt. Ich habe den Serverprozess beendet und konnte immer noch mit dem NSDictionary Objekt auf der client-Seite rumspielen.

    Nun wenn man explizit byref angibt wird tatsächlich ein NSDistantObject Instanz zurückgegeben und es gibt ein Timed out wenn man den Server beendet und mit dem Ergebnis NSDictionary Objekt rumspielt. Der Code sieht dann so aus:


    Quellcode

    1. @protocol DictReceiver
    2. - (byref NSDictionary*)dictionary;
    3. @end
    4. @interface Server : NSObject<DictReceiver> {
    5. }
    6. - (NSDictionary*)dictionary;
    7. @end


    Ich fand das etwas schwammig und wollte mal nachfragen. Was, wie und unter welchen Umständen (OS Version Tiger Leopard z.B.) das Default-Verhalten ist?

    Hat das vielleicht was mit den implementierten Protokollen der Ergebnisobjekte zu tun (NSCoding oder so)?
    Coding is poetry. Cocoa the inspiration (Meine Posts bitte nicht mit IE betrachten. Ich tue das auch nicht.)
  • Ok. Ich habe einiges gefunden und werde es mal posten.

    1. Das habe ich von einem Stepwise-Artikel

    Unlike the other keywords, PDO has no consistent default for this. Without the keyword, objects such as the immutable foundation kit objects will tend to be sent as copies while all other objects are sent as proxies.


    na toll :( Es wird auch nirgends dokumentiert welche Klassen sich wie verhalten.

    2. Um eigene Objekte mit bycopy zu transferieren muss man das NSCoding Protokol implementieren.

    viele Grüße!
    Coding is poetry. Cocoa the inspiration (Meine Posts bitte nicht mit IE betrachten. Ich tue das auch nicht.)
  • Viel kann ich dazu nicht sagen, da ich zwar versucht habe die Distributed Objects für GNUstep / mySTEP nachzubauen, aber NSPortCoder habe ich nicht 100% geschafft zu analysieren.

    Jedenfalls ist klar dass mindestens konstante NSStrings als bycopy geschickt werden. Und wahrscheinlich auch NSValue / NSNumber. Daraus ließe sich sogar schon alles andere byref ableiten.

    Klassen (Subklassen) können übrigens selbst definieren wie sie codiert werden wollen, d.h. man kann das verändern. Vielleicht ist es deshalb nicht exakt dokumentiert.

    -- hns
  • 1. Das sollte dich auch nicht interessieren, da ein Proxy für dich das Originalobjekt ist. Mutables (Entitäten und mutable Container) müssen synchronisiert werden. Da wird sich der Aufwand nicht lohnen, jedes Mal das ganze Dingens durch die Leitung zu schicken. Zumal daran ja wieder Objekte hängen können usw. Mutmaßlich ist es daher schon bei Collections (mutable und immutable) ungünstig, eine Kopie zu fertigen, ganz bestimmt von den verwiesenen Objekten. Bei immutable "skalaren" Objekten (NSString, NSNumber, NSValue, NSDate, NSData, NSDecimalNumber usw.) dürfte es indessen günstiger sein, eine Kopie anzufertigen, weil die ja nie mehr "hinterher geschickt" werden muss.

    Aber wie gesagt: Das ist Implementationsdetail und interessiert dich als Anwender eigentlich nicht.

    2. Klar, muss für eine Kopie das Coding-Protokoll implementiert werden. Dieses findet immer dann Anwendung, wenn es darum geht, aus einem sperrigen Objekt einen Bytestrom zu machen. Und durch die Leitung passen nun einmal nur Bytes, keine Objekte.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von coconut

    1. Das habe ich von einem Stepwise-Artikel

    Unlike the other keywords, PDO has no consistent default for this. Without the keyword, objects such as the immutable foundation kit objects will tend to be sent as copies while all other objects are sent as proxies.



    Nach dem Hinweis habe ich noch mal geschaut und das gefunden:
    aus Cocoa Programming; Anguish, Buck, Yacktman, S. 875:

    Some classes in the Cocoa frameworks are implemented to use bycopy. For example, when collection classes such as NSArray are passed over a connection, the collection itself is copied, but the objects contained in the remote copy of the collection are proxies to the original objects. The byref keyword is used to force the creation of a proxy instead of a copy if that is the desired behavior.

    NOTE
    The bycopy and byref keywords can only be used in protocol declarations, and they only apply to object arguments and return values.

    Meine Vermutung jetzt ist, das alle unveränderlichen Containerobjekte bycopy gesendet werden, aber letztlich müsste das jemand untersuchen.
    I would be embarrassed if they did not spy on me.
  • Das sollte dich auch nicht interessieren, da ein Proxy für dich das Originalobjekt ist.


    Aber es gibt doch byref und bycopy genaus aus dem Grund damit man sich dafür intressieren darf :)

    Anderseits: Das wäre echt gut, wenn ich mich dafür nicht zu ntressieren brauche. Leider handelt es sich tatsächlich um viele immutable Objekte die ich in einem Array Controller verwenden möchte. Die Daten brauche ich auch nicht zu synchronisieren oder mehmals abzufragen.

    Ich bin auf zwei Problemen gestossen:

    1. Laut Apple ist NSDistantObject unter Tiger nicht KVO kompatible. Daher darf ich keine Proxies in Array Controllern haben wenn ich zwischen Leopard und Tiger kommunizieren will.

    2. Ich möchte die Daten auch weiter benutzen können, wenn der Server nicht mehr läuft.

    Ach und eine dritte wäre: Wenn man den Array Controller umsortiert, werden für alle Einträge die valueForKey: Methoden aufgerufen die jedes mal über die Socketkommunikation gehen muss. Und bei über 1000 Einträgen sinkt die Geschwindigkeit deutlich ab.

    Dieses findet immer dann Anwendung, wenn es darum geht, aus einem sperrigen Objekt einen Bytestrom zu machen. Und durch die Leitung passen nun einmal nur Bytes, keine Objekte.


    Kommunikation zwischen PPC und Intel ist dabei, denke ich mal, nicht beeinträchtigt oder? (Beides 32 bit)

    Klassen (Subklassen) können übrigens selbst definieren wie sie codiert werden wollen, d.h. man kann das verändern.


    Klingt intressant. Wie geht das?
    Coding is poetry. Cocoa the inspiration (Meine Posts bitte nicht mit IE betrachten. Ich tue das auch nicht.)
  • Original von coconut
    Das sollte dich auch nicht interessieren, da ein Proxy für dich das Originalobjekt ist.


    Aber es gibt doch byref und bycopy genaus aus dem Grund damit man sich dafür intressieren darf :)

    Kommt ja auf die Seite an … Implementierer vs. Nutzer.

    Original von coconutAnderseits: Das wäre echt gut, wenn ich mich dafür nicht zu ntressieren brauche. Leider handelt es sich tatsächlich um viele immutable Objekte die ich in einem Array Controller verwenden möchte. Die Daten brauche ich auch nicht zu synchronisieren oder mehmals abzufragen.

    Dann scheint mir übers Netz eine Kopie preiswerter zu sein. (Genau umgekehrt wäre es in einem gemeinsamen Adressraum.)

    Original von coconut
    Ich bin auf zwei Problemen gestossen:

    1. Laut Apple ist NSDistantObject unter Tiger nicht KVO kompatible. Daher darf ich keine Proxies in Array Controllern haben wenn ich zwischen Leopard und Tiger kommunizieren will.

    Unter Leopard sind sie das? Huch, muss ich mir anschauen! meinst du wirklich KVO oder KVC? Verwechselt man leicht … :(

    Original von coconut2. Ich möchte die Daten auch weiter benutzen können, wenn der Server nicht mehr läuft.

    Es hindert dich ja niemand, selbst Kopien zu erstellen. Bedenke, dass Kopien von immutable Containern (fast) kostenlos sind. Die Methode sieht bei denen gedanklich so aus:

    Quellcode

    1. - (id)copy {return self; }


    Original von coconutAch und eine dritte wäre: Wenn man den Array Controller umsortiert, werden für alle Einträge die valueForKey: Methoden aufgerufen die jedes mal über die Socketkommunikation gehen muss. Und bei über 1000 Einträgen sinkt die Geschwindigkeit deutlich ab.

    Nachvollziehbar. Hier kannst du wirklich daran denken, selbst Kopien anzufertigen. Ich habe das mit Proxies aber noch nie gemacht: Probieren geht über studieren.

    Original von coconut
    Dieses findet immer dann Anwendung, wenn es darum geht, aus einem sperrigen Objekt einen Bytestrom zu machen. Und durch die Leitung passen nun einmal nur Bytes, keine Objekte.


    Kommunikation zwischen PPC und Intel ist dabei, denke ich mal, nicht beeinträchtigt oder? (Beides 32 bit)

    Endianess? Wenn du da ein Problem findest, schreibe eine Wut-Mail an Apple.

    Original von coconut
    Klassen (Subklassen) können übrigens selbst definieren wie sie codiert werden wollen, d.h. man kann das verändern.


    Klingt intressant. Wie geht das?

    Stammt nicht von mir. Aber mutmaßlich meint hns das Coding-Protokoll. Schau dir die Klasse und die verlinkten Dokumente an. Ist simpel.

    ––– (Kann nicht sein)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Unter Leopard sind sie das? Huch, muss ich mir anschauen! meinst du wirklich KVO oder KVC? Verwechselt man leicht


    Yep! Mit richtigen Observern. Ich ändere in NSTableView auf der client-seite die Werte via ArrayController die NSDistantObject's beinhalten und schon ist der NSTableView auf der Server-Seite aktualisiert :)

    Aber ich konnte keine Dokus dazu finden :(
    Coding is poetry. Cocoa the inspiration (Meine Posts bitte nicht mit IE betrachten. Ich tue das auch nicht.)
  • Original von coconut
    Unter Leopard sind sie das? Huch, muss ich mir anschauen! meinst du wirklich KVO oder KVC? Verwechselt man leicht


    Yep! Mit richtigen Observern. Ich ändere in NSTableView auf der client-seite die Werte via ArrayController die NSDistantObject's beinhalten und schon ist der NSTableView auf der Server-Seite aktualisiert :)

    Aber ich konnte keine Dokus dazu finden :(

    Kewl, ich wollte das immer in eine Postgre-Lib einbauen. Das geht dann ja so etwas einfacher …
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von coconut
    Klassen (Subklassen) können übrigens selbst definieren wie sie codiert werden wollen, d.h. man kann das verändern.


    Klingt intressant. Wie geht das?
    Schaue mal in das Beispiel in der Beschreibung von -replacementObjectForPortCoder:

    Dort kann man entweder das Original oder ein Distant Object zurückgeben.

    Es steht da auch noch ein Wichtiger Satz: "NSObject’s implementation returns an NSDistantObject object for the object returned by replacementObjectForCoder:, enabling all objects to be distributed by proxy as the default."

    D.h. der Default aller von NSObject abgeleiteten Objekte ist "byref". Wie das NSArray, NSDictionary, NSString usw. gemäß dem Beispiel überschreiben muß man ausprobieren (eigene Subclass von NSPortCoder anlegen die einen einstellbaren Wert für -isByref ausspuckt und dann replacementObjectForCoder aufrufen und das Ergebnis angucken ob es ein proxy ist oder nicht).

    -- hns