Objective-C Änderungen zwischen O 2.2.1 und O 3?
-
06-07-2019 - |
Frage
Wenn ich meine Anwendung versucht Kompilieren für OS 3 traf ich einen folgenden Fehler:
Fehler: Art der Accessor nicht die Art der Immobilie überein
Der Fehler war für eine Eigenschaft Ich habe versucht, dass für den Zugriff ist wie folgt definiert:
NSMutableArray *myArray
@property (readonly,nonatomic) NSArray* myArray;
die Eigenschaft wird in der Implementierungsdatei @synthesized.
Das funktionierte gut in O 2.2.1 aber nicht ist O 3.0
Das Schreiben der Getter-Methode selbst das Problem gelöst.
Ist jemand bewusst Änderungen an Objective-C zwischen O 2.2.1 und 3.0? Gibt es eine Dokumentation für diese Veränderungen?
Die API Änderungen dokumentieren nichts über dieses Thema zu enthalten scheint.
EDIT
der Fehler tritt auf, wenn Sie versuchen, die Eigenschaft zuzugreifen z.B.
NSArray *anArray = myClass.myArray;
Wie ich bereits erwähnt ich eine Abhilfe für dieses gefunden: das Schreiben der Getter-Methode selbst, aber was ich wirklich bin nach ist eine Art von Dokumentation von Apple erklärt, diese Änderung und alle anderen Änderungen, die nicht API verwandt sind
Danke für Ihre Hilfe
Lösung
Dies ist ein Compiler-Fehler.
Auch wenn Sie es nicht vollständig angeben, erwarte ich Ihren Code sieht wie folgt aus:
@interface Foo : NSObject {
NSMutableArray *objects;
}
@property (readonly, copy) NSArray *objects;
@end
@implementation Foo
@synthesize objects;
@end
Der Compiler ist leider verwirrt zwischen der Erklärung der objects
Eigenschaft und der Erklärung des objects
Instanzvariable . Denken Sie daran, dass die Eigenschaften und Instanzvariablen sind verschiedene Dinge in Objective-C; eine Eigenschaft kann durch eine Instanz Variable gesichert werden, aber es ist ein Teil der öffentlichen Schnittstelle einer Klasse wirklich.
Sie können, indem Sie den Code dieses Problem umgehen, um klar die Definition der Instanzvariablen aus der Definition der Immobilie trennen, beispielsweise durch den Namen der Instanzvariablen prefixing:
@interface Foo : NSObject {
NSMutableArray *_objects;
}
@property (readonly, copy) NSArray *objects;
@end
@implementation Foo
@synthesize objects = _objects;
@end
Auf diese Weise der Compiler nicht verwirrt über die Immobilie im Vergleich zu der Instanzvariable in Ausdrücken wie self.objects
bekommt (was es nicht ohnehin sollte, aber anscheinend der Fall ist).
Nur die unvermeidliche Reaktion auf dem Kopf ab: Apple- nicht behalten underbar Präfix zum Beispiel Variablen. Es ist für Methoden vorbehalten. Unabhängig davon, ob Sie die underbar nicht mögen, können Sie einen anderen Präfix zu verwenden.
Andere Tipps
Bearbeiten Original Antwort entfernt, nachdem Peer Review fand es fehlt. Bitte lesen Sie Chris Hanson Kommentare zu diesem Thema. Ich verlasse den Rest hier, weil ich denke, es ist immer noch gültig ist.
Beachten Sie, dass selbst wenn Sie den Objekttyp deklarieren werden NSArray
, kehrte das Objekt ist immer noch ein NSMutableArray
und die änderbaren Methoden ist für sie definiert. Deklarieren der Eigenschaft auf diese Weise tut nicht verhindern jemand aus Versehen das Array mutiert.
Wenn Sie sicher sein wollen, dass das zurückgegebene Array nicht wandelbar ist, können Sie die Eigenschaft wie in Ihrem ursprünglichen Beispiel erklären, und dann Ihre eigene Accessor rollen:
- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }
Beachten Sie, dass dies eine nicht retardierte NSArray
zurückzukehren. Es würde bis zu dem Anrufer sein Eigentum an dem Gegenstand zu nehmen, wenn es nötig zu anhalten.
Sie sehen Fehler, weil XCode jetzt Warnungen und Fehler für Dinge Ausgabe tat es nicht vorher ...
Ich würde behaupten, dass es höchstens eine Warnung sein sollte, zu tun, was Sie tun, ich verstehe Ihren Versuch das Array als unveränderlich an der Außenwelt zu präsentieren, sondern habe es innerhalb der Klasse wandelbar. Vielleicht möchten Sie eine andere Accessor mit einem anderen Namen prüfen, gebaut speziell die änderbaren Array zurück.
Es ist noch Objective-C 2.0; Der Compiler ist nur vielleicht ein wenig mit der Prüfung dieser Art von Typ aktualisiert einen Fehler zu ändern. Es ziemlich viel sollte ein Fehler sein. Zumindest sollte es Sie warnen, dass Sie wahrscheinlich nicht bedeuten, was Sie geschrieben haben. Dann könnten Sie Zeug werfen, um es nicht zu machen Sie warnen, die Sie nicht mit der @synthesize
Aussage machen kann.
Ich habe gerade genau Ihren Code und eine synthesize Anweisung in meinen Controller eingefügt und ich habe keine Fehler oder Warnungen über sie. Sie baute in Ordnung. Jetzt habe ich die Basis-SDK „Simulator 3.0“, und die Build auf „Simulator 3.0 Debug“. Dieses Projekt hatte im 2.2.1 SDK gestartet und ich installierte nur den 3.0 SDK gestern; Xcode ist Version 3.1.3.
Aktualisieren :. Oh, ich sehe, dass tatsächlich versucht, die Eigenschaft zu setzen, wo Sie erhalten die Fehler, den Sie erwähnt
self.myArray = [NSArray arrayWithObject:@"foo"];
Klar kann man dieses Verhalten nicht @synthesize
und müssen Ihre eigenen Accessoren schreiben.
- (NSArray*)myArray {
return [NSArray arrayWithArray:myArray];
}
- (void)setMyArray:(NSArray*) pMyArray {
myArray = [NSMutableArray arrayWithArray:pMyArray];
}
Das Ausfüllen dieser Accessoren, nicht die Nachricht weggehen, also musste ich den Zugang zu ändern:
[self setMyArray:[NSArray arrayWithObject:@"foo"]];
die obige Syntax verwenden, ohne benutzerdefinierten Zugriffs hat auch nicht funktioniert.
PS Wow, ist jemand verärgert, dass man weder kopieren Nachricht Blasen, oder der Text im Bauergebnisse Fenster?
Das ist also wirklich mit dem @synthesize Anruf zu tun, die nicht glücklich ist über eine NSMutableArray als NSArray auszusetzen -. Warum nicht nur die getMethod implementieren
Eigentlich darüber denke, es muss die Set-Methode, die nicht glücklich ist -. Sie würdest eine NSArray setzen in eine NSMutableArray nicht in der Lage sein
Ihre Fragen lauteten:
Ist jemand bewusst Änderungen an Objective-C zwischen O 2.2.1 und 3.0?
Gibt es eine Dokumentation für diese Veränderungen?
Die endgültigen Antworten sind:
1) Es gab keine vorsätzliche Änderungen der Sprachspezifikation, aber der Compiler und andere Entwickler-Tools geändert. Chris und seine Mitarbeiter sind die Experten auf diese Veränderungen.
2) Wahrscheinlich nicht, weil alle Änderungen waren unbeabsichtigte oder besser aufeinander abzustimmen Verhalten mit der Dokumentation gemacht.
Sie sollten nicht so schnell Chris' Antwort auf die Frage zu entlassen ‚eine Vermutung.‘ Chris arbeitet auf der Apple-Entwickler-Tools. Sie könnten eine andere Antwort Sie mehr mögen, aber Sie finden nicht eine kompetente Antwort bekommen.