Apples "Cocoa Application Tutorial" - Probleme unter 10.4

O

ozzyrocks

Mitglied
Thread Starter
Dabei seit
25.06.2006
Beiträge
68
Reaktionspunkte
0
Hallo,

ich habe mir gerade das Cocoa Application Tutorial (Currency Converter) (http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/) von Apple angeschaut. Das ist schon für 10.5 angepasst, ich habe jedoch noch 10.4.

Da steht dann, dass ich in diesem Falle statt
@property(readwrite) float sourceCurrencyAmount, rate;
die Methoden von Hand deklarieren muss. Soweit so gut.

Im Implementation-Teil steht dann allerdings nicht mehr, was ich für 10.4 anders machen muss, und
@synthesize sourceCurrencyAmount, rate;
geht unter 10.4 nicht.

Folgende Fehler und Warnungen erhalte ich:
error: request for member 'sourceCurrencyAmount' in something not a structure or union
error: request for member 'rate' in something not a structure or union
warning: control reaches end of non-void function
warning: incomplete implementation of class 'Converter'
warning: method definition for '-setRate:' not found
warning: method definition for '-rate' not found
warning: method definition for '-setSourceCurrencyAmount:' not found
warning: method definition for '-sourceCurrencyAmount' not found

Ich denke mal, die "method definition"-Warnungen kommen daher, dass die @synthesize-Anweisung nicht geht. Aber was ist das Problem bei den beiden errors, kommt das auch daher?

So sieht die convertCurrency-Methode aus:
- (float)convertCurrency {
return self.sourceCurrencyAmount * self.rate;
}

Gibt es vielleicht von diesem Dokument noch irgendwo die 10.4-Version? unter /Developer/Documentation/ ist nichts, das Unterverzeichnis Cocoa/ existiert nicht mal.

Grüße
ozzyrocks
 
Hallo!

Die getter/setter Implementierung ist so nicht richtig. 10.4 kennt die self<dot>foo Syntax nicht, die ist erst ein Feature von Obj-C 2.0:
Code:
- (float)convertCurrency {
return self.sourceCurrencyAmount * self.rate;
}
Richtig wäre:
Code:
- (float)convertCurrency {
return sourceCurrencyAmount * rate;
}

Viele Grüsse
Christian
 
Aha, danke! Und wozu ist das self dann gut bei ObjC 2.0, wenn man es bei 1.0 gar nicht braucht?

Die @synchronize-Anweisung ist aber bei ObjC 2.0 der Ersatz für das manuelle Implementieren der getter/setter-Methoden?

Existiert bei dir das Verzeichnis /Developer/Documentation/Cocoa/ ? Dort soll nämlich diese pdf-Datei (vielleicht in der älteren Fassung?) liegen. Das Unterverzeichnis Cocoa/ gibt es bei mir aber gar nicht.

Grüße
ozzyrocks
 
Hallo!

Das self brauchst Du auch bei Obj-C 1.0. Damit kannst sich z.B. das Objekt selber Nachrichten schicken:

Code:
[self sayHello];

@synthesize, nicht @synchronize ;-) Letzteres gibt es auch, das Keyword verhält sich aber so wie unter Java und synchronisiert Zugriffe auf Instanz Variablen.

Und ja, das @synthesize baut Dir die Getter/Setter Combo automatisch und spart Tipparbeit.

Code:
$ l /Developer/Documentation/
total 0
drwxrwxr-x  9 root      admin  306 27 Okt 17:15 CHUD/
drwxrwxr-x  6 _devdocs  wheel  204  5 Nov 14:34 DocSets/
drwxrwxr-x  3 root      admin  102 27 Okt 17:15 Perl/
drwxrwxr-x  4 root      admin  136 27 Okt 17:15 Python/
drwxrwxr-x  5 root      admin  170 24 Sep 07:55 RubyCocoa/
drwxrwxr-x  5 root      admin  170 27 Okt 17:15 wxWidgets/
Das Verzeichnis existiert bei mir auch nicht.

Viele Grüsse
Christian
 
Und wie würden die getter/setter-Methoden aussehen, wenn ich sie von Hand schreiben würde?

Ist das so richtig:

Code:
- (float)rate {
	return rate;
}

- (void)setRate:(float)newRate {
	rate = newRate;
}

Grüße
ozzyrocks
 
Yepp, für primitive Datentypen ist das so richtig. Bei Objekten sieht die Sache etwas anders aus, vor allem wenn man keine Garbage Collection verwenden möchte oder verwenden kann. Der einfachste Ansatz ist dann die retain/release Kombination:

Code:
- (MyObject *)object {
    return object;
}

- (void)setObject:(MyObject *)o {
    [o retain];
    [object release];
    object = o;
}
Man erhöht also zuerst den Reference Counter auf neue Object und erniedrigt danach den Zähler auf die lokale Referenz. Danach kann man der lokalen Referenz das neue Objekt zuweisen.

Viele Grüsse
Christian
 
Zuletzt bearbeitet:
Zu den objektbasierten Datentypen:

Wenn ich den Getter aufrufe, dann erhalte ich eine Referenz auf das Originalobjekt, richtig? D.h. ich kann dieses dann auch verändern?

Und beim Setter übergebe ich eine Referenz auf ein bereits vorher von mir erstelltes Objekt. Was genau macht dann [o retain];?

[object release] ruft dann den Destruktor für das alte Objekt auf, dann wird eine Referenz (?) des neuen Objekts übergeben. Ist das so richtig?

Grüße
ozzyrocks
 
Wenn ich den Getter aufrufe, dann erhalte ich eine Referenz auf das Originalobjekt, richtig? D.h. ich kann dieses dann auch verändern?

Das kommt darauf an, wie der Setter implementiert ist, und was Du unter "Originalobjekt" verstehst.
Der Setter kann mit "retain" oder "copy" arbeiten.

Und beim Setter übergebe ich eine Referenz auf ein bereits vorher von mir erstelltes Objekt. Was genau macht dann [o retain];?
Siehe oben. Es gibt setter, die mit retain implementiert sind, andere mit copy. Das hängt ganz davon ab, was man haben möchte

[object release] ruft dann den Destruktor für das alte Objekt auf, dann wird eine Referenz (?) des neuen Objekts übergeben. Ist das so richtig?
Nein, das ist doppelt falsch.

release ruft nur dann den Destruktor (dealloc) auf, wenn der retain count bei 0 ist.
Und release gibt gar nichts zurück.

Alex
 
Zurück
Oben Unten