Private Methoden selber Basteln

  • Private Methoden selber Basteln

    Hallo,

    kennt jemand eine Möglichkeit, in einer Methodenimplementation die Instanz zu ermitteln, die die Methode aufgerufen hat?
    Mir geht es darum, dass ich gerne private (echt private, nicht nur versteckte) Methoden benutzen würde. Man könnte natürlich den Aufrufer in der Methode selbst mitgeben, das wäre aber jederzeit unterwanderbar.
    Und wenn wir schon dabei sind, kennt jemand den Grund, warum das nicht in Obj-C verhergesehen ist?

    Gruss,
    Johannes
  • RE: Private Methoden selber Basteln

    In C++ verwenden manche das Pimpl-Idiom, was auch in Objective-C klappen sollte:

    Du machst eine "oeffentliche" Klasse, die nur Methoden hat, welche Du wirklich rausgeben willst. Diese Klasse macht nichts anderes, als nur alle Aufrufe an eine versteckte, "private" Klasse weiter zu geben. So kommt niemand an die privaten Methoden ran.
    C++
  • RE: Private Methoden selber Basteln

    Original von zermelo
    In C++ verwenden manche das Pimpl-Idiom, was auch in Objective-C klappen sollte:

    Du machst eine "oeffentliche" Klasse, die nur Methoden hat, welche Du wirklich rausgeben willst. Diese Klasse macht nichts anderes, als nur alle Aufrufe an eine versteckte, "private" Klasse weiter zu geben. So kommt niemand an die privaten Methoden ran.


    Dann wird eben die private Klasse verwendet ;)

    Chris
    Man macht einfach solange irgendwelche Dinge, bis man tot ist.
    Und dann bekommen die anderen Kuchen.
  • RE: Private Methoden selber Basteln

    Original von zermelo
    In C++ verwenden manche das Pimpl-Idiom, was auch in Objective-C klappen sollte:

    Du machst eine "oeffentliche" Klasse, die nur Methoden hat, welche Du wirklich rausgeben willst. Diese Klasse macht nichts anderes, als nur alle Aufrufe an eine versteckte, "private" Klasse weiter zu geben. So kommt niemand an die privaten Methoden ran.

    Damit lässt sich der Aufrufer ermitteln?
    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 johannesauer
    Hmm, scheint mir auch unterwanderbar, oder habe ich da was falsch verstanden? Natürlich kann man es einfach "nicht machen", aber das gilt ja schon für versteckte Methoden. Lieber wäre mir was echt privates...

    Gruss,
    Johannes

    Wenn es dir darum geht, die Methoden zu "scannen", geht das mit AOP. Irgendwer sitzt da gerade an einem Framework. Der Aufrufer lässt sich derzeit nicht unmittelbar ermitteln, das wird aber kommen. Habe ich mir jedenfalls fest vorgenommen. :) (Du kannst prinzipiell mit [[NSThread mainTrhead] callStack] den Aufrufer ermitteln, ist aber etwas frickelig.)

    Der Grund, warum das nicht geht, ist, dass das ein Seiteneffekt wäre. Der Aufrufer gehört nicht zum Kontext, in dem die Methode läuft.
    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"?
  • Hi,

    also meine idee ist ganz einfach, dass in der Implementation der Aufrufer einer Methode ermittelt wird. Mal angenommen es würde bei jedem Methodenaufruf der Aufrufer versteckt mitgegeben, ich nenne das mal "aufrufer"

    Quellcode

    1. - (void)privateMethode
    2. {
    3. if (aufrufer == self)
    4. {
    5. //private Dinge
    6. }
    7. }


    Oder ist da ein Denkfehler drin? Ich kennt mich mit der Runtime leider gar nicht aus...

    Gruss,
    Johannes
  • Wie schaut das denn bei anderen Sprachen aus? Mich wundert es, das es das nicht wirklich gibt...die Lösung von Apple über extensions ist ja auch nicht optimal...aber wie gesagt, von der Runtime hab ich keine Ahnung.

    Der Grund, warum das nicht geht, ist, dass das ein Seiteneffekt wäre. Der Aufrufer gehört nicht zum Kontext, in dem die Methode läuft.


    Hätte das denn negative Auswirkungen?
  • RE: Private Methoden selber Basteln

    Original von Chris
    Dann wird eben die private Klasse verwendet ;)

    Die private Klasse kannst Du ganz weit weg packen, und bspw. nur compiliert mitgeben. Dann muss das ganze Interface reverse-engineered werden, um darauf zugreifen zu können.

    Davon abgesehen ist es schwierig, an die private Instanz zu kommen, um an diese Nachrichten überhaupt zu senden (wenn man denn mal das Interface kennt).

    Ich verstehe noch nicht ganz den praktischen Anwendungsfall. Wenn ich das richtig verstehe, hast Du bspw. ein Framework, was jeder haben kann, aber niemand soll -geheim() daran aufrufen können, ausser das Framework intern?

    Ich mein, Du könntest auch Dein eigenes objc_msgSend mitbringen, aber was soll so tief versteckt werden?

    Amin Negm-Awad
    Damit lässt sich der Aufrufer ermitteln?

    Ich entschuldige mich, wenn in meinem Post nicht offensichtlich genug zu erkennen war, dass ich eine Alternative vorschlagen wollte. Trollst Du?
    C++
  • Hi,

    der Anwendungsfall ist kein Spezieller, also kein Framework, ich würde einfach gerne den Zugriff einschränken. Dadurch könnte man einfach solidere Programme schreiben. Man kann natürlich gegenargumentieren und sagen, solange man nicht auf "private" methoden von aussen zugreift, reicht es, diese zu kennzeichnen. Aber das ist kein schöner Ansatz...mir ist einfach konzeptionell nicht klar, warum es geschützte Members gibt, aber keinen geschützten Methoden. Hat da jemand eine Begründung? Ist das konzeptionell so gewollt oder einfach eine Schwäche von Obj-C? Oder würde man sich andere Probleme einhandeln (schlechte Laufzeit, usw)?

    Gruss,
    Johannes
  • Soweit ich das verstanden habe, liegt das daran, dass niemand weiss, auf welche Methoden ein Objekt reagiert - und ensprechend noch viel weniger weiss, wer diese aufrufen darf.

    Das ganze ist in Python ähnlich, da ich hier auch zur Laufzeit Funktionen erstellen und verändern kann, und auch Python hat keine "richtigen" privaten Methoden, an die wirklich niemand heran kommt.

    Also was ist jetzt schlecht an meinem Pimpl-Vorschlag, würde das Problem doch lösen. Nur wer sich aus der Wrapper-Klasse den internen Pointer organisieren kann und die genaue Signatur der internen Methoden kennt, kann auch an diese Nachrichten schicken. Das ist schon sehr schwierig, hinzubekommen.
    C++
  • Original von johannesauer
    Ich würde einfach gerne den Zugriff einschränken. Dadurch könnte man einfach solidere Programme schreiben.


    wie stellst du dir das vor?
    wer schreibt denn das programm?
    Du schreibst eine klasse und packst nur das in den header/doku was die leute verwenden sollen welche diese klasse benutzen sollen/dürfen. Wer etwas anderes machen will, hat immer die möglichkeit dazu - was da etwas solider machen sollte sehe ich nicht
  • Jaaaa, das stimmt natürlich. Aber ich sehe da trotzdem einen Unterschied. Nur weil man da rumtricksen kann, heisst das ja nicht, es macht keinen Sinn, den Zugriff einzuschränken. Wer wissenlich rumtrickst ist selbst schuld, wenn der Rechner explodiert. Zugegeben, man kann einfach sagen, Warnung = Fehler, aber warum gibt es nicht einfach @protected und @private auch für Methoden? Was wäre denn der Nachteil? Finde ich seltsam...
    Aber vielleicht gibt es ja einen, nur erkenne ich ihn nicht.

    Gruss,
    Johannes
  • Original von johannesauer
    Jaaaa, das stimmt natürlich. Aber ich sehe da trotzdem einen Unterschied. Nur weil man da rumtricksen kann, heisst das ja nicht, es macht keinen Sinn, den Zugriff einzuschränken. Wer wissenlich rumtrickst ist selbst schuld, wenn der Rechner explodiert. Zugegeben, man kann einfach sagen, Warnung = Fehler, aber warum gibt es nicht einfach @protected und @private auch für Methoden? Was wäre denn der Nachteil? Finde ich seltsam...
    Aber vielleicht gibt es ja einen, nur erkenne ich ihn nicht.

    Gruss,
    Johannes


    na jetzt verrat uns mal welcher schuh dich drückt:

    was stört dich dran eine methode die du privat haben willst nicht in den header bzw die doku zu packen die dann die andren leute verwenden sollen?
    denn wenn du ihnen die infos darüber nicht gibst, müssen sie sich die methodennamen der klasse auch mittels "class-dump", "otoolit", "nm" und co beschaffen. Gibst du den leuten den sourcecode selbst, hindert sie ja eh nix dran direkt den code zu verändern oder ein @private oder @protected zu entfernen - also was ist das problem? Nenn doch mal ein konkretes beispiel!