Ich verwende derzeit das iOS 5 SDK, um meine App zu entwickeln. Ich versuche, einen NSString zu einer Eigenschaft zu machen und ihn dann in der .m-Datei zu synthetisieren (ich habe dies zuvor ohne Probleme getan). Jetzt stieß ich auf Folgendes: "Semantisches Problem: Der synthetisierte Getter von Property folgt der Cocoa-Namenskonvention für die Rückgabe von Objekten im Besitz."
Das ist mein Code: .h
@interface ViewController : UIViewController {
NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;
.m
@synthesize newTitle;
Hat jemand eine Ahnung, wie ich das beheben könnte? Vielen Dank!!
Ich vermute, dass die von Ihnen verwendete Compilerversion auch für deklarierte Eigenschaften - genauer gesagt für Accessoren deklarierter Eigenschaften - die Speicherverwaltungsregeln lautet:
Sie übernehmen das Eigentum an einem Objekt, wenn Sie es mit einer Methode erstellen, deren Name mit "alloc", "new", "copy" oder "mutableCopy" beginnt.
Eine Eigenschaft mit dem Namen newTitle
liefert bei der Synthese eine Methode mit dem Namen _-newTitle
_, daher die Warnung/der Fehler. _-newTitle
_ soll eine Getter-Methode für die Eigenschaft newTitle
sein. Die Namenskonventionen besagen jedoch, dass eine Methode, deren Name mit new
beginnt, ein Objekt zurückgibt, dessen Eigentümer der Aufrufer ist, was bei Getter-Methoden nicht der Fall ist.
Sie können dies lösen, indem Sie:
Diese Eigenschaft umbenennen:
_@property (strong, nonatomic) NSString *theNewTitle;
_
Behalten Sie den Eigenschaftsnamen bei und geben Sie einen Getternamen an, der nicht mit einem der speziellen Präfixe für den Methodennamen beginnt:
_@property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
_
Behalten Sie sowohl den Eigenschaftsnamen als auch den Getternamen bei und teilen Sie dem Compiler mit, dass der Gettername, obwohl er mit new
beginnt, im Gegensatz zur Methodenfamilie none
zur Methodenfamilie new
gehört:
_#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non-clang compilers
#endif
#if __has_attribute(objc_method_family)
#define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
#else
#define BV_OBJC_METHOD_FAMILY_NONE
#endif
@interface ViewController : UIViewController
@property (strong, nonatomic) NSString *newTitle;
- (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
@end
_
Beachten Sie, dass, obwohl Sie mit dieser Lösung newTitle
sowohl als Eigenschaftsname als auch als Gettername beibehalten können, eine Methode mit dem Namen _-newTitle
_, die kein Objekt zurückgibt, dessen Eigentümer der Aufrufer ist, für andere Personen, die Ihren Code lesen, verwirrend sein kann .
Für den Datensatz haben Apple veröffentlicht Übergang zu ARC Release Notes , in denen sie angeben:
Sie können einer Eigenschaft keinen Namen geben, der mit
new
odercopy
beginnt.
Ihnen wurde bereits mitgeteilt, dass ihre Aussage nicht ganz korrekt ist: Der Schuldige ist der Name der Getter-Methode, nicht der Name der Eigenschaft.
Edit 17 Jan 2015: Ich habe gerade ein Commit für Clang bemerkt, das Option 3 oben vorschlägt (Verwenden von objc_method_family(none)
), einschließlich eines Fix-It, für den allgemeinen Fall, dass ein Eigenschaftsname mit einem der speziellen Präfixe der Methodenfamilie übereinstimmt. Xcode wird diese Änderung wahrscheinlich irgendwann übernehmen.
#arc # automatisch synthetisiert # xcode-4.6.1
** EDIT **
Anscheinend können Sie mutableCopy auch nicht verwenden.
Der Name des Mitglieds, der mit new beginnt, löst die Warnung aus. Ändern Sie den Namen in editedTitle und die Warnung verschwindet. Ich konnte keine Dokumentation finden, die dies bestätigt, konnte aber durch Testen feststellen, dass Membervariablen, die mit "new" beginnen, den Compiler erschweren.
ARC erlaubt nicht, "Neu ...." im Eigenschaftsnamen zu verwenden. Sie können jedoch "newTitle" verwenden, indem Sie den Getternamen ändern.
@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
Es sieht nicht so aus, als ob Bavarious das vorgeschlagen hätte, was Sie tun wollten. Sie möchten lediglich eine Instanzvariable NewTitle
deklarieren und dann die Eigenschaft synthetisieren. Früher mussten die Instanzvariable und die Eigenschaft deklariert werden. Nicht mehr.
Ich glaube, der richtige Weg, dies zu tun, ist der folgende:
.h
@interface ViewController : UIViewController
@property (nonatomic, strong) NSString *newTitle;
.m
@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
Die Instanzvariable für die Eigenschaft newTitle
wird synthetisiert. Sie möchten nicht, dass Ihre Instanzvariable mit Ihrer Eigenschaft übereinstimmt - zu leicht, um Fehler zu machen .
Siehe Beispiel: Deklarieren von Eigenschaften und Synthetisieren von Accessoren
Wenn Sie in CoreData im Attribut "new ..." verwenden (normalerweise kompilieren), stürzt es mit der Ausnahme "bad access" nach dem Zufallsprinzip ab.
Es gibt kein Absturzprotokoll und die mit "All Exceptions Breakpoint" angezeigte Zeile hilft Ihnen überhaupt nicht.
Wenn Sie einen Setter manuell mit demselben Namen wie die Eigenschaft schreiben, wird diese Warnung entfernt.
Abgesehen von dem Problem, dass Sie "new" vor Ihren Eigenschaftsnamen verwenden sollten/können, sagen wir noch eines: Versuchen Sie, "new" vor Namen im Allgemeinen zu vermeiden. "Neu" ist zeitabhängig. Derzeit ist es für Sie neu, aber einige Zeit später möchten Sie möglicherweise wieder etwas Neues implementieren. Die Verwendung von "new" in Namen ist also immer schlecht. Versuchen Sie so zu denken: In der Programmierwelt schafft "neu" immer etwas: eine neue Instanz von etwas.
In Ihrem Fall, wenn Sie einen anderen Titel als den aktuellen Namen Ihrer Eigenschaft titleReplacement zuweisen möchten.
Eine weitere Sache: Versuchen Sie, Funktionen und Methoden zuerst mit dem Verb zu benennen, wie setSomething oder getSomething. Versuchen Sie jedoch in Eigenschaften, das Objekt zuerst zu benennen, z. B. heightMinimum, heightMaximum usw. -> Wenn Sie beim Codieren Ihren Inspector verwenden, suchen Sie immer nach Objekten. Versuch es. ;-)
NS_RETURNS_NOT_RETAINED
wird verwendet, um das Namensproblem zu lösen.
@property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;
Wir können sein Definition wie folgt finden,
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
Das Attribut 'ns_returns_not_retained' ist das Komplement von 'ns_returns_retained'. Wenn eine Funktion oder Methode den Cocoa-Konventionen zu entsprechen scheint und ein beibehaltenes Cocoa-Objekt zurückgibt, kann dieses Attribut verwendet werden, um anzugeben, dass die zurückgegebene Objektreferenz nicht als "besitzende" Referenz betrachtet werden soll, die an den Aufrufer zurückgegeben wird. Das Foundation-Framework definiert ein Makro NS_RETURNS_NOT_RETAINED, das funktional dem unten gezeigten entspricht.
Fügen Sie weitere Details hier hinzu.