J'ai un objet dans obj-c à l'exécution, dont je ne connais que la clé KVC et j'ai besoin de détecter le type de valeur de retour (par exemple, j'ai besoin de savoir si un NSArray ou NSMutableArray) de cette propriété, comment puis-je faire cela?Comment détecter un type de retour de propriété dans Objective-C
Répondre
Vous parlez de l'introspection des propriétés d'exécution, qui se trouve être quelque chose que Objective-C est very good at.
Dans le cas que vous décrivez, je suppose que vous avez une classe comme ceci:
@interface MyClass
{
NSArray * stuff;
}
@property (retain) NSArray * stuff;
@end
Ce qui est encodée dans quelque chose XML comme ceci:
<class>
<name>MyClass</name>
<key>stuff</key>
</class>
De cette information, vous voulez pour recréer la classe et lui donner également une valeur appropriée pour stuff
.
Voici comment il pourrait ressembler:
#import <objc/runtime.h>
// ...
Class objectClass; // read from XML (equal to MyClass)
NSString * accessorKey; // read from XML (equals @"stuff")
objc_property_t theProperty =
class_getProperty(objectClass, accessorKey.UTF8String);
const char * propertyAttrs = property_getAttributes(theProperty);
// at this point, propertyAttrs is equal to: [email protected]"NSArray",&,Vstuff
// thanks to Jason Coco for providing the correct string
// ... code to assign the property based on this information
documentation d'Apple (lien ci-dessus) a tous les détails sales sur ce que vous pouvez vous attendre à voir dans propertyAttrs
.
En fait, il serait égal à T @ "NSArray", &, Vstuff ;-) –
Merci, vous avez absolument raison. J'ai fait le changement –
Merci, cela semble être le meilleur moyen, je vais l'essayer. Btw. votre exemple est assez proche de ce que je fais, mais il peut s'agir de n'importe quel fichier xml, donc ma clé est le nom de l'élément. – Enyra
Vous pouvez utiliser un message isKindOfClass
if([something isKindOfClass:NSArray.class])
[somethingElse action];
le problème est, l'objet est nouvellement créé, de sorte que la valeur de la propriété est nulle. J'ai juste une clé KVC, dont je ne sais pas si l'objet a vraiment cet accesseur, mais s'il l'a, j'ai besoin de connaître le type de cette valeur de retour sans avoir l'objet en question. – Enyra
Pourquoi ne pas prendre votre décision logique plus tard quand vous aurez un objet? L'objectif C est plus le langage d'exécution que statique. –
@Enyra: c'est bon. En utilisant ce qui précède, si l'objet est nul, il retournera false même s'il finit par être un tableau. –
Le meilleur moyen est d'utiliser les méthodes définies dans le NSObject Protocol. Plus précisément, pour déterminer si quelque chose est une instance d'une classe ou d'une sous-classe de cette classe, vous devez utiliser -isKindOfClass:
. Pour déterminer si quelque chose est une instance d'une classe particulière, et que cette classe (c.-à-: non une sous-classe), utilisez -isMemberOfClass:
Alors, pour votre cas, vous voulez faire quelque chose comme ceci:
// Using -isKindOfClass since NSMutableArray subclasses should probably
// be handled by the NSMutableArray code, not the NSArray code
if ([anObject isKindOfClass:NSMutableArray.class]) {
// Stuff for NSMutableArray here
} else if ([anObject isKindOfClass:NSArray.class]) {
// Stuff for NSArray here
// If you know for certain that anObject can only be
// an NSArray or NSMutableArray, you could of course
// just make this an else statement.
}
Dans le cas Enyra 'anObject' est nul. Regardez les commentaires dans ma réponse. –
Ce test ne fonctionnera pas. Tous les tableaux, même immuables, sont issus de NSMutableArray. – Chuck
isMemberOfClass: est la vérification qui ignore l'héritage. –
Bonne réponse: utilisez the NSObject+Properties source here.
Il met en œuvre la même méthodologie décrite ci-dessus.
+1 pour la bonne lib :) – Kjuly
J'aime souvent réinventer la roue, donc je vais probablement faire quelque chose comme ça et utiliser cette bibliothèque comme exemple/référence. Merci beaucoup! –
Ceci est vraiment un commentaire adressant un problème soulevé par Greg Maletic en réponse à la réponse fournie par e.James 21APR09. Convenu qu'Objective-C pourrait utiliser une meilleure implémentation pour obtenir ces attributs. Voici une méthode que je rapidement jeté ensemble pour récupérer les attributs d'une propriété unique objet:
- (NSArray*) attributesOfProp:(NSString*)propName ofObj:(id)obj{
objc_property_t prop = class_getProperty(obj.class, propName.UTF8String);
if (!prop) {
// doesn't exist for object
return nil;
}
const char * propAttr = property_getAttributes(prop);
NSString *propString = [NSString stringWithUTF8String:propAttr];
NSArray *attrArray = [propString componentsSeparatedByString:@","];
return attrArray;
}
Liste partielle des clés d'attributs:
- R Lecture seule
- C Copie de la dernière valeur affectée
- & référence à la dernière valeur attribuée
- N nonatomic propriété
- W référence faible
la liste complète, Apple
Note concernant l'édition de Slipp D. Thompson de la messagerie entre parenthèses à la syntaxe à points: La modification de la syntaxe à points ci-dessus entraînera une erreur de compilation pour l'appel "obj.class" dans Xcode 6.4 et Xcode 7 Beta besoin de mettre à jour la déclaration "id" à "NSObject" pour résoudre). Je suis partisan de l'opinion de Jon Reid selon laquelle l'utilisation de la syntaxe point pour la messagerie dans ObjC est généralement imprudente: http://qualitycoding.org/dot-notation/#comments – Jalakoo
Si vous savez que la propriété est définie:
id vfk = [object valueForKey:propertyName];
Class vfkClass = vfk.class;
Et comparez avec isKindOfClass, issubclass, etc.
Que faire si la valeur actuelle est nulle? – JBlake
- 1. Comment spécifier un type de propriété d'objet dans Spring.NET
- 2. DynamicData: utiliser un type personnalisé comme type de retour
- 3. Comment appliquer un attribut .net à un type de retour
- 4. Analyseur AMF0 dans ObjectiveC
- 5. Comment détecter le type de serveur Web
- 6. Comment détecter si le type est un autre type générique
- 7. ensemble opération sur un retour de la propriété IList travaille
- 8. Propriété/valeur de retour pour cette variable?
- 9. Rendre mysql_fetch_assoc automatiquement détecter les types de données de retour?
- 10. Valeur de retour de propriété de dépendance WPF
- 11. Comment détecter une modification dans la propriété Text d'un TextBlock?
- 12. De retour type incorrect d'une fonction
- 13. génériques java - méthode de retour type
- 14. type retour dynamique d'une fonction
- 15. Paramètre de propriété de type primitive dynamique dans l'objectif C
- 16. Retour du type correct après l'utilisation de OrderBy()
- 17. Quitter Installation à partir d'une action personnalisée (méthode publique dans un assembly géré) Type de retour
- 18. Delphi 2009 - Propriété de type Enum personnalisé dans l'inspecteur d'objets
- 19. Comment détecter le type MIME d'un fichier téléchargé dans ASP.NET?
- 20. C# Type Dynamique dans une propriété GenericCollection
- 21. Comment détecter un modificateur de clavier dans un bookmarklet?
- 22. Comment puis-je émettre un type .NET avec deux propriétés qui sont surchargées uniquement sur le type de retour?
- 23. silverlight, comment implémenter une propriété de type StoryBoard
- 24. Type de retour à partir de méthodes db
- 25. C# retour au type var?
- 26. Comment accéder à une propriété de type BOOL?
- 27. Détecter un événement de clavier dans C
- 28. Si je me joins à un linq-to-sql, quel type de retour ai-je?
- 29. Comment détecter un appel Selector.wakeup
- 30. Comment détecter un changement de sélection CListCtrl?
D'où vient l'information vient de votre fichier XML? Serait-il possible d'ajouter une entrée pour indiquer le type de chaque propriété? –
Le fichier xml est également hors de mon contrôle. Je crée un sérialiseur xml qui convertit un fichier xml dans une structure d'objet. Bien sûr, les objets doivent être disponibles, mais j'ai besoin d'informations sur l'objet lors de l'exécution pour remplir correctement les données. – Enyra