1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Objective-C 2.0 - Declared Properties (Unklarheit)

Dieses Thema im Forum "OS X-Developer" wurde erstellt von Poljpocket, 03.10.08.

  1. Poljpocket

    Poljpocket Salvatico di Campascio

    Dabei seit:
    07.01.07
    Beiträge:
    432
    Hallo Leute, ich habe eine sehr grundlegende Frage:

    Ich möchte in Zukunft meine Klassen auch mittels properties deklarieren können. Beim Lesen der dazugehörenden Core Reference - Seiten ist folgende Unklarheit aufgetaucht:

    Mir ist nicht ganz klar, wie die getter-Methode eines copy-propertys aussieht!

    Code:
    @property(copy) NSString *myName;
    Die setter-Methode (Inhalt) sieht dann ja so aus:

    Code:
    if (property != newValue)
    {
    [INDENT][property release];
    property = [newValue copy];[/INDENT]
    }
    Wie sieht jetzt die getter-Methode aus?

    Konkret, mein Ziel wäre es, die getter-Methode (Inhalt) automatisch in etwa so aussehen zu lassen:

    Code:
    return [[property copy] autorelease];
    Ist das mit diesen "Property Declaration Attributes" direkt möglich, oder muss ich die getter-Methode selber immer implementieren? (Ich glaube, das hat auch noch was mit atomic/non-atomic zu tun, nicht?)

    boah, viele Fragen, danke für eure Antworten!

    Gruß ppocket
     
  2. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
    @synthesize propertyname in der Implementationsdatei bzw.
    @dynamic propertyname wenn Du CoreData benutzt. Der Compiler bzw. das Framework stellen dann automatisch die richtigen getter/setter bereit (trotzalledem ist es möglich, eigene zu schreiben).
    Um copy zu ermöglichen, muss die Eigenschaft noch das NSCopying Protokoll implementieren
    http://developer.apple.com/document...s/NSCopying_Protocol/Reference/Reference.html

    Gruß, SMJ
     
  3. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Das ist so nicht richtig.@dynamic ist immer dann anzuwenden,wenn
    a) du dieAccessoren selbst programmierst.
    b) du die Accessoren erst zur Laufzeit erzeugst.

    Weil aber @dynamic der Default ist und bei a) der Compiler angesichts ausformulierter Methoden nicht meckert, benötigt man es in diesem Falle nicht explizit. Genereische Core-Data-Accessoren sind dann ein Fall von b), der allerwichtigste sogar, aber eben nur ein Fall.

    Ja,weil @dynamic Default ist.

    Das war nicht seine Frage. Er spielt auf das Trheading-Problem bei Gettern an, wie ich es bereits in der zweiten Auflage ab Seite 166 erläutere.
     
  4. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    If you do not specify nonatomic, then in a managed memory environment a synthesized get accessor for an object property retains and autoreleases the returned value; if you specify nonatomic, then a synthesized accessor for an object property simply returns the value directly.

    Also:
    1. copy] autorelease] ist bei einem Getter eigentlich Lötzinn. Das -copy dient ja der Kapselung und diese erreichst du bei einem Getter durch eine anständige Typisierung (NSString* anstelle von NSMutableString* usw.)

    2. Ein threadfestes retain] autorelease] bekommst du per Default, wenn du einfach kein nonatomic spezifizierst.
     
  5. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
    Meine Fresse Amin,

    ich rege mich jetzt nicht über Klugscheißerei auf...
    Manchmal habt Ihr einen Ton drauf, da vergeht einem echt die Lust, sich hier zu beteiligen.
    Er hat gefragt, ich hab ihm geantwortet (dass das Thema umfangreich ist, wird schon beim Lesen von Apples Doku klar und lässt sich nun mal nicht in einem schnellen Post nebenbei behandeln...) und KEINERLEI Bedarf, mir diese Toller-Hecht-Ich-Habs-Drauf-Sprüche zu geben...

    Bitte, wenn Ihr so schlau seid...hier höre ich mir gerne Antworten in obigen Ton an:

    http://www.osxentwicklerforum.de/thread.php?threadid=7825

    Soweit, SMJ
     
  6. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Sorry, aber du hast zum einen seine Frage nicht beantwortet. Er hat eine dezidierte Frage dazu gestellt, bei der es um das -autorelease ging. Dies macht den Getter threadfest.

    Zum anderen hast du etwas geschrieben, was so nicht richtig ist. Deshalb habe ich geschrieben, dass es so nicht richtig ist. Ich weiß ja nicht, wie du das siehst, aber wenn hier demnächst einer vorbeikommt und das so liest, lernt er schlicht etwas Falsches. Das kann ja nun nicht dein Interesse sein.

    Wenn du damit ein Problem hast, korrigiert zu werden, ist das definitiv dein Problem.

    Zu dem Link: Vielleicht solltest du auch hier daran denken, dass man es den Antwortern einfach macht und ein Mini-Projekt hochlädt. Du glaubst doch nicht, dass das jetzt jemand nachbaut, um dir zu helfen, wo du es doch auf deiner Festplatte liegen hast.

    Übrigens, so viel schon dazu:
    1. NSTableViews adaptieren das Dragging-Protokoll.
    2. Ich verstehe auch schon nicht, warum du das beim Tableview-Delegate erwartest, ist doch das Tableview die Draggin-Source.
    3. Wenn du mal die D&D-Doku angesehen hättest, findest du dort einen eigenen Abschnitt für Tableviews.
    4. Ja, wenn man das Standardverhalten von Tableviews beim Dragging ändern möchte, muss man das ableiten. - wie jedes andere View.
     
  7. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
    Entweder bin ich blöd, oder es war doch seine Frage...

    Genau darauf bezog sich meine Antwort.
    Dass @dynamic noch mehr Fälle abdeckt, steht in der Doku und ist mir selber klar.
    Danke trotzdem für den Hinweis.

    Das war nicht seine Frage, sondern Deine Vermutung, weil Du es in Deinem Buch auf Seite 166 geschrieben hast :-D

    Ich habe von niemandem verlangt, das nachzubauen, es hätte ja sein können, dass es im OSX-Entwicklerforum (anders als hier im thematisch breiter gefächerten Apfeltalk) jmd. gibt, der das vielleicht fix parat hat - offensichtlich nicht.
    Meine Anfrage ist auch nicht so formuliert, dass jetzt jeder sofort losspringen soll, wie schon gesagt, der Ton macht die Musik.

    Hättest Du meinen Beitrag gelesen, hättest Du gemerkt, dass ich das getan habe - ich benutze genau die Methoden aus selbigen Abschnitt und schreibe das ja auch...so what?

    Danke, genau dieser Satz hätte völlig ausgereicht.

    Nein, habe ich nicht. S.o., Ton...Musik...
     
  8. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Darauf willst du keine Antwort … ;)

    Scherz beiseite: Er hat nicht gefragt, die die Deklaration einer Eigenschaft aussieht (@property), sondern wie die daraus resultierenden Methoden (wenn überhaupt dann bezogen auf @synthesize) aussehen. Insbesondere hat er gefragt, ob die ein copy] autorelease] ausführen.

    Diese Frage ist wichtig für Threading. Wird kein (in Wahrheit: ) retain] autorelease] durchgeführt, sind die Getter nicht threadfest. Siehe hierzu wie bereits erwähnt Rodewig/Negm-Awad, Objective-C und Cocoa, 2. Auflage, S. 166


    Nein, deine Antwort bezog sich auf die nicht gestellte Frage, wie man eine Eigenschaft deklariert.

    Ich kann ja nicht wissen, was dir klar ist. Ich kann nur wissen, was du schreibst. Und das war hier zu "eng". Ich hatte deshalb auch geschrieben, dass es "so" nicht richtig sei. Es war ja nicht wirklich falsch, nur "gequetscht".


    Es war seine Frage, sogar fast wörtlich:
    Doch, ich machte das Mal in meiner Anwaltssoftware so, um Mandanten aus einer Akte zu entfernen. Letztlich ist es aber Blödsinn, weil das mit [Entf] viel einfacher geht und es fast sämtliche Programme so machen.

    Aber davon unabhängig muss man das dann für Leopard noch einmal komplett nachprüfen. Der Aufwand ist nicht unerheblich.

    Ich habe auch nicht behauptet, dass sie so formuliert sei. Es ist aber die Folge deiner Anfrage, ob gewollt oder nicht. Und daher entspricht es nicht im geringsten einem höflichen Umgangston, wenn du hier losbefiehlst, man solle sich darum kümmern. Die Leute, die das nämlich machen, geben damit Arbeitszeit und Betriebsgeheimnisse preis. Du solltest also bitten und danken.

    Dann hättest du sehen können, dass die Delegate-Methoden nnicht] Methoden des Dragging-Source-Protokolles sind. Du hättest im Übrigen sehen können, dass dein Delegate nicht die Dragging-Source ist.

    Aber was sollen wir hier die OT-Diskussion führen …


    Da bin ich aber außerordentlich froh, dass ich dir helfen konnte.

    Meinst du diesen hier:
     
    #8 Amin Negm-Awad, 08.10.08
    Zuletzt bearbeitet: 08.10.08
  9. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
    An Deinem ganzen Post merkt man, dass Du Jurist bist - machst Deine Sache sicher gut...
    Um es gleich vorweg zu sagen, ich schätze Deine Kompetenz wirklich sehr (Cocoa), Du antwortest schnell und kommst auf den Punkt - insofern will ich jetzt die, von meiner Seite ins polemische abgerutschte, Diskussion beenden und mich für den etwas rüden Ton bei Dir entschuldigen.

    Trotz alledem nur noch ein paar Worte zu meinem, zugegebenerweise etwas scharf formulierten Post:

    Manchmal antwortet man auf Fragen, die oft von Cocoa Anfängern kommen, eben nicht in dem Umfang, wie es für Leute wie Dich womöglich richtiger wäre. Ich finde es auch gut, dass Du Dein Wissen dann hier teilst.
    Ich finde es aber dennoch ermüdend, mir dann einen recht oberlehrerhaften Ton in Deiner Antwort auf meine reinzuziehen (Dein Post ist kompetent und auf den Punkt, keine Frage, ich habe meinen ersten Post auf dem Flughafen 10min vorm einchecken geschrieben, da war keine Zeit):

    Das verdirbt mir manchmal die Lust, mich hier zu beteiligen und das kann ja auch nicht im Sinne eines Forums sein. Darauf wollte ich ursprünglich hinaus.
    Ich will jetzt hier auch nicht die beleidigte Leberwurst spielen, die Sache ist für mich geklärt.


    Gruß, SMJ
     
  10. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Ich habe generell nichts dagegen, verinfachend zu antworten. Das mache ich selbst häufig genug. Allerdings sollte man das dazu schrieben. (BTW: Angesichts seiner Fragestellung ist er kein Anfänger.)

    Und, sorry, wenn du "Das war nicht seine Frage" als oberlehrerhaft einschätzt, kann ich dir nicht folgen.
     
  11. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
    Hab mir den ganzen Thread nochmal in Ruhe durchgelesen - ist echt peinlich, was ich da zusammenschreibe...

    Nochmals sorry und auf ein Neues!

    Gruß, SMJ
     
  12. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Quatsch, peinlich ist das nun wirklich nicht. Mutmaßlich hast du einfach durch den knappen Ton meiner Antwort als "Abfertigung" verstanden. War nicht so gemeint. Hätte ich klarer machen sollen. Mea culpa.

    Schwamm drüber.

    Pack schlägt sich, Pack verträgt sich. In diesem Sinne müssen wiir ein gemeinsames Bier saufen. (Also es hat jeder schon sein eigenes.)
    http://www.osxentwicklerforum.de/thread.php?threadid=7906
     
  13. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
    Indeed :)
    Klappt Job-bedingt bei mir da leider nicht, aber was nicht is...die erste Runde geht dann auf mich!
     
  14. sumpfmonsterjunior

    sumpfmonsterjunior Morgenduft

    Dabei seit:
    17.03.05
    Beiträge:
    167
  15. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Ah, schön. Vor allem stimme ich ihm darin zu, dass man aus der Lösung atomic, um den Getter threadsafe zu machen (genauer, wie er ganz richtig sagt: transaktionsfest) nicht schließen darf,
    dass die Applikation threadfest ist. Das schreibe ich aber auch schon in der letzten Auflage. IIRC auch in meinem Speicherverwaltungsartikel dazu in der OS-X-Entwicklerforum-Wiki. Ich finde daher die retain] autorelease] Lösung auch etwas kurz gegrifffen.
     
  16. Der Paule

    Der Paule Königsapfel

    Dabei seit:
    26.05.07
    Beiträge:
    1.200
    Projektweite Zugriffsmethoden?

    Moin,

    passenderweise buddel ich diesen Thread wieder aus, anstatt einen neuen aufzumachen.
    Es geht um folgendes: Wie kann ich öffentliche Zugriffsmethoden nutzen um Eigenschaften aus einer andere Klasse heraus setzen zu können?

    Ich kenne die Zugriffsmethoden von C# und Java. Dort sind diese natürlich public gesetzt um damit den Zugriff auf private gesetzte Eigenschaften von Klassen zu steuern. Nur wie läuft das in Objective-C?

    Wenn ich die Zugriffsmethoden mit @property und @synthesize setzte erhalte ich eine Warnung beim Zugriff auf die Methode von einer anderen Klasse aus:
    [​IMG]

    Beim ausführen des Programms trotz Warnung bekomme ich eine Fehlermeldung in der Konsole:
    2009-01-16 17:35:37.729 BinaryCalculator[82910:10b] *** +[controller strInput:]: unrecognized selector sent to class 0x3060


    Interface zu den Eigenschaften sieht wie folgt aus:

    Code:
    @interface controller : NSObject 
    {
        NSString *strInput;
        NSString *strOutput;
    }
    
    @property (retain) NSString* strInput;
    @property (retain) NSString* strOutput;
    
    @end
    
    Inplementierung so:

    Code:
    @implementation controller
    
    @synthesize strInput;
    @synthesize strOutput;
    
    @end
    
    Aufruf aus einer anderen Klasse sieht wie folgt aus:

    Code:
    @implementation viewcontroller
    
    -(void)convertBinToDec:(id)sender
    {
        [controller strInput:@"test"];
        [txtInput setStringValue:[controller strInput]];
    }
    
    @end
    
    Hier zu sehen ist der direkte Zugriff ohne vorher ein Objekt zu erstellen. Allerdings gehts mit erstellten Objekt auch nicht und erhalte die selbe Warnung und Fehlermeldung.

    So nun meine Frage, da ich im Netz keine passende Antwort gefunden habe und Anhand von Beispielen auch nicht erkennbar ist, da diese immer nur mit einer Klasse arbeiten.
    Wie kann ich Klasseneigenschaften Projekt weit beeinflussen mit Hilfe von Zugriffsmethoden in Objective-C?

    Danke schonmal.

    mfg
    paule
     

    Anhänge:

  17. Jamsven

    Jamsven London Pepping

    Dabei seit:
    21.11.07
    Beiträge:
    2.046
    Du hast keine setter Methoden.
    Fehler:
    Code:
    [controller [COLOR="Red"]set[/COLOR]strInput:@"test"];
    Also ich würde:
    Code:
    @property(readwrite, copy) NSString *strInput;
    schreiben.
    readwrite deklariert Getter/Setter- Methoden.
    copy kopiert den neuen Wert und referenziert das Attribut auf die Kopie.

    Ich glaube nicht das readwrite default ist, aber ich lasse mich auch eines besseren Belehren.
    Im allgemeinen müssen die Accesorensignaturen so aussehen:

    Getter: -(Datentyp)attributName;
    Setter: -(void)setAttributName: (Datentyp)whatEver;

    Sonst kannst "key value coding/observing" vergessen, da diese die standarisierten Signaturen aufrufen.
     
    #17 Jamsven, 16.01.09
    Zuletzt bearbeitet: 16.01.09
  18. Der Paule

    Der Paule Königsapfel

    Dabei seit:
    26.05.07
    Beiträge:
    1.200
    Nabend,

    nun habe ich eine Lösung gefunden die funktioniert.
    Dem @property lassen sich Attribute mitgeben. Das Attribut "readwrite" ist laut Apple Referenz default. Genauso wie "assign". Allerdings muss man "assign", "retain", oder "copy" angeben. Weitere Eigenschaften wie "readonly" sind alle optional. Somit war die @property Anweisung korrekt. Läuft als Setter und Getter Methode.
    Siehe dazu die Apple Referenz zu Declared Properties.

    Mein Fehler war der Aufruf der Zugriffsmethoden, die in der Apple Referenz nicht angegeben ist.
    Diese habe ich auf der Webseite mit der Übersicht über Obective-C 2.0 in Leopard gefunden.

    Mein Aufruf vorher:

    Code:
    @implementation viewcontroller
    
    -(void)convertBinToDec:(id)sender
    {
        [controller strInput:@"test"];
        [txtInput setStringValue:[controller strInput]];
    }
    
    @end 
    
    Hier der richtige Aufruf:

    Code:
    @implementation viewcontroller
    
    -(void)convertBinToDec:(id)sender
    {
        controller *con  = [[controller alloc]init];
        con.strInput = @"Test";
        NSLog(con.strInput);
    }
    
    @end
    
    Trotzdem danke für die Hilfe.

    mfg
    paule
     
  19. Jamsven

    Jamsven London Pepping

    Dabei seit:
    21.11.07
    Beiträge:
    2.046
    Ok, aber trotzdem verstehe ich nicht warum bei dir die setter-Methode anscheindend:
    Code:
    -(void)strInput:(NSString*)x
    ist.
    Selbst deine verlinkte Refernenz erklärt:
    Ergo muss sie bei deinem Code:
    Code:
    -(void)setStrInput:(NSString*)x
    heißen.

    Der erste Code ist demnach auch richtig, du hast nur den falschen Methodennamen geschrieben.
    Vergleiche dazu auch Hillegass 3.Ausg S.144-145. Leider hab ich vom Amin nur das alte Buch, da gabs die Dot-Notation und propertys noch gar net.

    Btw.: Hillegass kritisiert Apple für diese Dot Notation, da Methodenaufrufe schon fest definiert sind.
     
  20. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Das ist sie beim ihm ja auch nicht. Deshalb bekommt er ja die Warnung vom Compiler und die Fehlermeldung zur Laufzeit.

    Wie kann der erste Code richtig sein, wenn er den falschen Methodennamen geschrieben hat? ;)
    Neben dem falschen Methodennamen hat er die Nachricht auch noch ans Klassenobjekt geschickt und nicht an eine Instanz der Klasse. Objektive-C unterscheidet Klassenmethoden (+methode) und Instanzmethoden (-methode)!

    MacApple
     

Diese Seite empfehlen