Objective-C 2.0 - Declared Properties (Unklarheit)

Poljpocket

Salvatico di Campascio
Registriert
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
 

sumpfmonsterjunior

Morgenduft
Registriert
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
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
@synthesize propertyname in der Implementationsdatei bzw.
@dynamic propertyname wenn Du CoreData benutzt.
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.

@synthesize propertyname in der Implementationsdatei Der Compiler bzw. das Framework stellen dann automatisch die richtigen getter/setter bereit (trotzalledem ist es möglich, eigene zu schreiben).
Ja,weil @dynamic Default ist.

@synthesize propertyname in der Implementationsdatei Um copy zu ermöglichen, muss die Eigenschaft noch das NSCopying Protokoll implementieren
http://developer.apple.com/document...s/NSCopying_Protocol/Reference/Reference.html
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.
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
[…]
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?)[…]
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.
 

sumpfmonsterjunior

Morgenduft
Registriert
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
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
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
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.
 

sumpfmonsterjunior

Morgenduft
Registriert
17.03.05
Beiträge
167
Mir ist nicht ganz klar, wie die getter-Methode eines copy-propertys aussieht!

Code:
@property(copy) NSString *myName;

Amin Negm-Awad schrieb:
Das war nicht seine Frage.

Entweder bin ich blöd, oder es war doch seine Frage...

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?
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.

Amin Negm-Awad schrieb:
...Er spielt auf das Trheading-Problem bei Gettern an...
Das war nicht seine Frage, sondern Deine Vermutung, weil Du es in Deinem Buch auf Seite 166 geschrieben hast :-D

Amin Negm-Awad schrieb:
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.

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.

Amin Negm-Awad schrieb:
3. Wenn du mal die D&D-Doku angesehen hättest, findest du dort einen eigenen Abschnitt für Tableviews

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?

Amin Negm-Awad schrieb:
Ja, wenn man das Standardverhalten von Tableviews beim Dragging ändern möchte, muss man das ableiten. - wie jedes andere View
Danke, genau dieser Satz hätte völlig ausgereicht.

Amin Negm-Awad schrieb:
Wenn du damit ein Problem hast, korrigiert zu werden, ist das definitiv dein Problem.
Nein, habe ich nicht. S.o., Ton...Musik...
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Entweder bin ich blöd, oder es war doch seine Frage...
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


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

Dass @dynamic noch mehr Fälle abdeckt, steht in der Doku und ist mir selber klar.
Danke trotzdem für den Hinweis.
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".


Das war nicht seine Frage, sondern Deine Vermutung, weil Du es in Deinem Buch auf Seite 166 geschrieben hast :-D
Es war seine Frage, sogar fast wörtlich:
Konkret, mein Ziel wäre es, die getter-Methode (Inhalt) automatisch in etwa so aussehen zu lassen:

Code:
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 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.
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.

Meine Anfrage ist auch nicht so formuliert, dass jetzt jeder sofort losspringen soll, wie schon gesagt, der Ton macht die Musik.

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.

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?
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 …


Danke, genau dieser Satz hätte völlig ausgereicht.
Da bin ich aber außerordentlich froh, dass ich dir helfen konnte.

Nein, habe ich nicht. S.o., Ton...Musik...
Meinst du diesen hier:
Bitte, wenn Ihr so schlau seid...hier höre ich mir gerne Antworten in obigen Ton an:
 
Zuletzt bearbeitet:

sumpfmonsterjunior

Morgenduft
Registriert
17.03.05
Beiträge
167
...Scherz beiseite....

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 war nicht seine Frage...

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
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
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.
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Hab mir den ganzen Thread nochmal in Ruhe durchgelesen - ist echt peinlich, was ich da zusammenschreibe...
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.

Nochmals sorry und auf ein Neues!
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
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
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.
 

Der Paule

Königsapfel
Registriert
26.05.07
Beiträge
1.199
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:
attachment.php


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

  • Warnung.png
    Warnung.png
    10,7 KB · Aufrufe: 200

Jamsven

London Pepping
Registriert
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.
 
Zuletzt bearbeitet:

Der Paule

Königsapfel
Registriert
26.05.07
Beiträge
1.199
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
 

Jamsven

London Pepping
Registriert
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:
@property float value;
is equivalent to:

- (float)value;
- (void)setValue: (float)newValue;
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.
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
Ok, aber trotzdem verstehe ich nicht warum bei dir die setter-Methode anscheindend:
Code:
-(void)strInput:(NSString*)x
ist.
Das ist sie beim ihm ja auch nicht. Deshalb bekommt er ja die Warnung vom Compiler und die Fehlermeldung zur Laufzeit.

Der erste Code ist demnach auch richtig, du hast nur den falschen Methodennamen geschrieben.
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