Wie kann ich in Objective-C eine Liste (in Form eines NSArray
oder NSDictionary
) bestimmter Objekteigenschaften abrufen?
Stellen Sie sich das folgende Szenario vor: Ich habe eine übergeordnete Klasse definiert, die nur erweitert wird NSObject
und ein NSString
, ein BOOL
und ein NSData
Objekt als Eigenschaften enthält. Dann habe ich mehrere Klassen, die diese übergeordnete Klasse erweitern und jeweils viele verschiedene Eigenschaften hinzufügen.
Gibt es eine Möglichkeit, eine Instanzmethode für die übergeordnete Klasse zu implementieren , die das gesamte Objekt durchläuft und beispielsweise eine NSArray
der (untergeordneten) Klasseneigenschaften zurückgibt, da NSStrings
diese nicht für die übergeordnete Klasse gelten, sodass ich diese später verwenden kann? NSString
für KVC?
[NSString stringWithCString:]
wird zugunsten von abgelehnt[NSString stringWithCString:encoding:]
.Die Antwort von @ boliva ist gut, benötigt aber ein wenig mehr, um mit Grundelementen wie int, long, float, double usw. umgehen zu können.
Ich habe aus seiner aufgebaut, um diese Funktionalität hinzuzufügen.
quelle
#import <Foundation/Foundation.h>
Wollten Sie oben in der .h-Datei haben?Die Antwort von @ orange80 hat ein Problem: Die Zeichenfolge wird nicht immer mit 0s beendet. Dies kann zu unerwarteten Ergebnissen wie Abstürzen führen, während versucht wird, es in UTF8 zu konvertieren (ich hatte tatsächlich nur deswegen einen ziemlich nervigen Absturzfehler. Es hat Spaß gemacht, ihn zu debuggen ^^). Ich habe es behoben, indem ich tatsächlich einen NSString aus dem Attribut abgerufen und dann cStringUsingEncoding: aufgerufen habe. Das funktioniert jetzt wie ein Zauber. (Funktioniert auch mit ARC, zumindest für mich)
Das ist also jetzt meine Version des Codes:
quelle
Als ich es mit iOS 3.2 versuchte, funktionierte die Funktion getPropertyType nicht gut mit der Eigenschaftsbeschreibung. Ich habe ein Beispiel aus der iOS-Dokumentation gefunden: "Objective-C Runtime Programming Guide: Deklarierte Eigenschaften".
Hier ist ein überarbeiteter Code für die Auflistung von Eigenschaften in iOS 3.2:
quelle
Ich habe festgestellt, dass die Lösung von Boliva im Simulator einwandfrei funktioniert, aber auf dem Gerät verursacht der Teilstring mit fester Länge Probleme. Ich habe eine objektiv-C-freundlichere Lösung für dieses Problem geschrieben, die auf dem Gerät funktioniert. In meiner Version konvertiere ich den C-String der Attribute in einen NSString und führe String-Operationen aus, um einen Teilstring mit nur der Typbeschreibung zu erhalten.
quelle
Diese Implementierung funktioniert sowohl mit Objective-C-Objekttypen als auch mit C-Grundelementen. Es ist iOS 8-kompatibel. Diese Klasse bietet drei Klassenmethoden:
Gibt ein Wörterbuch aller sichtbaren Eigenschaften eines Objekts zurück, einschließlich der Eigenschaften aller seiner Oberklassen.
Gibt ein Wörterbuch aller sichtbaren Eigenschaften einer Klasse zurück, einschließlich der Eigenschaften aller ihrer Oberklassen.
Gibt ein Wörterbuch aller sichtbaren Eigenschaften zurück, die für eine Unterklasse spezifisch sind . Eigenschaften für seine Oberklassen sind nicht enthalten.
Ein nützliches Beispiel für die Verwendung dieser Methoden ist das Kopieren eines Objekts in eine Unterklasseninstanz in Objective-C, ohne dass die Eigenschaften in einer Kopiermethode angegeben werden müssen . Teile dieser Antwort basieren auf den anderen Antworten auf diese Frage, bieten jedoch eine übersichtlichere Schnittstelle zu den gewünschten Funktionen.
Header:
Implementierung:
quelle
Wenn jemand auch die von den übergeordneten Klassen geerbten Eigenschaften abrufen muss (wie ich), werden hier einige Änderungen am " orange80 " -Code vorgenommen, um ihn rekursiv zu machen:
quelle
Das Wort "Attribute" ist etwas verschwommen. Meinen Sie Instanzvariablen, Eigenschaften, Methoden, die wie Accessoren aussehen?
Die Antwort auf alle drei lautet "Ja, aber es ist nicht sehr einfach." Die Objective-C-Laufzeit-API enthält Funktionen zum Abrufen der ivar-Liste, Methodenliste oder Eigenschaftsliste für eine Klasse (z. B.
class_copyPropertyList()
) und anschließend eine entsprechende Funktion für jeden Typ, um den Namen eines Elements in der Liste (zproperty_getName()
. B. ) abzurufen .Alles in allem kann es eine Menge Arbeit sein, es richtig zu machen, oder zumindest viel mehr, als die meisten Leute für das tun möchten, was normalerweise eine wirklich triviale Funktion ist.
Alternativ können Sie auch ein Ruby / Python-Skript schreiben, das nur eine Header-Datei liest und nach "Attributen" für die Klasse sucht.
quelle
Ich konnte die Antwort von @ orange80 erhalten, um mit ARC ENABLED zu arbeiten ... ... für das, was ich wollte - zumindest ... aber nicht ohne ein bisschen Versuch und Irrtum. Hoffentlich ersparen diese zusätzlichen Informationen jemandem den Kummer.
Speichern Sie die Klassen, die er in seiner Antwort = als Klasse beschreibt, und setzen Sie sie in Ihre
AppDelegate.h
(oder was auch immer)#import PropertyUtil.h
. Dann in Ihrem ...Methode (oder was auch immer)
…
Das Geheimnis ist die Instanz - Variable Ihrer Klasse (werfen in diesem Fall meine Klasse ist
Gist
, und meine InstanzGist
istgist
) , die Sie abfragen wollen ... zu NSObject ...(id)
, etc, wird es nicht .. schneiden für verschiedene, seltsame esoterische Gründe. Dies gibt Ihnen eine Ausgabe wie folgt ...Für all Apples unverfrorenes / OCD, das mit ObjCs "Amazeballs" "Selbstbeobachtung prahlt ... Sie machen es sicher nicht sehr einfach, diesen einfachen" Blick "" auf sich selbst "," sozusagen ", auszuführen.
Wenn du aber wirklich wild werden willst, dann schau dir das an. Class-Dump , das ist eine unglaublich verrückte Art, in Klassen-Header von JEDER ausführbaren Datei usw. zu schauen. Es bietet einen VERBOSE Blick in deine Klassen. persönlich finden wirklich hilfreich - unter vielen, vielen Umständen. Aus diesem Grund habe ich nach einer Lösung für die Frage des OP gesucht. Hier sind einige der Verwendungsparameter. Viel Spaß!
quelle
Du hast drei Zaubersprüche
Der folgende Code kann Ihnen helfen.
quelle
Ich habe die bereitgestellte Funktion boliva verwendet, aber anscheinend funktioniert sie nicht mehr mit iOS 7. Anstelle der statischen Eigenschaft const char * getPropertyType (Eigenschaft objc_property_t) kann jetzt nur Folgendes verwendet werden:
quelle
Für Swift-Zuschauer können Sie diese Funktionalität erhalten, indem Sie die
Encodable
Funktionalität nutzen. Ich werde erklären, wie:Passen Sie Ihr Objekt an das
Encodable
Protokoll anErstellen Sie eine Erweiterung für
Encodable
, umtoDictionary
Funktionen bereitzustellenRufen Sie
toDictionary
Ihre Objektinstanz auf und greifen Sie auf diekeys
Eigenschaft zu.Voila! Greifen Sie wie folgt auf Ihre Immobilien zu:
quelle
Diese Antworten sind hilfreich, aber ich brauche mehr davon. Ich möchte nur überprüfen, ob der Klassentyp einer Eigenschaft dem eines vorhandenen Objekts entspricht. Alle oben genannten Codes sind dazu nicht in der Lage, weil: Um den Klassennamen eines Objekts abzurufen, gibt object_getClassName () folgende Texte zurück:
Wenn Sie jedoch getPropertyType (...) aus dem obigen Beispielcode aufrufen, verwenden Sie 4 objc_property_t-Strukturen von Eigenschaften einer Klasse, die wie folgt definiert sind:
Es werden Zeichenfolgen wie folgt zurückgegeben:
Es kann also nicht festgestellt werden, ob ein NSObject der Wert einer Eigenschaft der Klasse sein kann. Wie geht das dann?
Hier ist mein vollständiger Beispielcode (die Funktion getPropertyType (...) ist dieselbe wie oben):
quelle