34 votes

Vérifiez si l'objet est de type Classe

J'ai une méthode qui reçoit un NSArray de Class objets et j'ai besoin de vérifier si ils sont tous à l' Class type généré avec le code ci-dessous:

NSMutableArray *arr = [[NSMutableArray alloc] init];

[arr addObject:[NSObject class]];
[arr addObject:[NSValue class]];
[arr addObject:[NSNumber class]];
[arr addObject:[NSPredicate class]];
[arr addObject:@"not a class object"];

Le problème est qu' Class n'est pas un objectif-la classe c, c'est une struc, donc je ne peux pas utiliser juste

    for (int i; i<[arr count]; i++) {
        Class obj = [arr objectAtIndex:i];

        if([obj isKindOfClass: [Class class]]) {
            //do sth
        }
    }

Donc, j'ai besoin d'-je vérifier si l' obj variable est un Class type, je suppose qu'il sera en C directement, mais comment puis-je le faire?

Il va être un plus si la réponse fournissent également un moyen de vérifier si l'élément du tableau est NSObject, comme les articles dans le code de l'exemple, l' NSPredicate serait également true de la NSObject vérifier

47voto

Joe Points 37343

Pour déterminer si un "objet" est d'une classe ou d'une instance, vous devez vérifier si il est un méta-classe dans un processus en deux étapes. Premier appel object_getClass puis de vérifier si c'est un méta-classe à l'aide d' class_isMetaClass. Vous devrez #import <objc/runtime.h>.

NSObject *object = [[NSObject alloc] init];
Class class = [NSObject class];

BOOL yup = class_isMetaClass(object_getClass(class));
BOOL nope = class_isMetaClass(object_getClass(object));

Les deux Class et *id ont la même structure de mise en page (Class isa), peut donc poser comme des objets, et peuvent recevoir des messages qu'il est difficile de déterminer qui est qui. Cela semble être la seule façon que j'ai été en mesure d'obtenir des résultats cohérents.

EDIT:

Voici l'original de votre exemple avec le chèque:

NSMutableArray *arr = [[NSMutableArray alloc] init];

[arr addObject:[NSObject class]];
[arr addObject:[NSValue class]];
[arr addObject:[NSNumber class]];
[arr addObject:[NSPredicate class]];
[arr addObject:@"not a class object"];

for (int i; i<[arr count]; i++) {
    id obj = [arr objectAtIndex:i];

    if(class_isMetaClass(object_getClass(obj)))
    {
        //do sth
        NSLog(@"Class: %@", obj);
    }
    else
    {
        NSLog(@"Instance: %@", obj);
    }
}

[arr release];

Et la sortie:

Catégorie: NSObject
Catégorie: NSValue
Catégorie: NSNumber
Catégorie: NSPredicate
Exemple: pas un objet de classe

8voto

user102008 Points 8748

Mise à jour: dans iOS 8+ ou OS X 10.10+, vous pouvez simplement faire:

 object_isClass(obj)
 

(Vous devrez #import <objc/runtime.h> .)

1voto

Deepak Danduprolu Points 33605

Si vous devez vérifier si l'objet dans le tableau est un objet Class vous pouvez vérifier s'il répond aux méthodes de classe.

 for ( id obj in arr ) {
    if (([obj respondsToSelector:@selector(isSubclassOfClass:)])
          && (obj == [NSObject class]) ) {
        NSLog(@"%@", obj);
    }
}
 

Une fois que vous savez qu'il s'agit d'un objet Class en vérifiant s'il répond à isSubclassOfClass: vous pouvez vérifier l'égalité directe avec [NSObject class] .

-4voto

Cyprian Points 7158

Aucun problème ici n'est de savoir comment vous le faites:

 if([NSStringFromClass([obj class]) isEqualToString:@"Class"]){
    NSLog(@"It is type of Class");
}
 

Éditer

Ou vous pouvez rendre votre classe conforme à un protocole: et vérifiez si l'obj que vous obtenez du tableau est conforme à ce protocole comme ceci:

 if([obj conformsToProtocol:@protocol(MyClassProtocol)])
 

Éditer

Ou vous pouvez vérifier si ce que vous obtenez de la baie est conforme à NSObject

 if ([object conformsToProtocol:@protocol(NSObject)]) {
    // Do something
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X