Prüfen Sie, ob das Objekt vom Typ Klasse ist

Lesezeit: 7 Minuten

Benutzer-Avatar
Philipp Sabino

Ich habe eine Methode, die a empfängt NSArray von Class Objekte und ich muss überprüfen, ob sie alle sind Class Typ generiert mit dem folgenden Code:

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"];

Das Problem ist, dass Class ist keine Objective-c-Klasse, es ist eine Struktur, also kann ich sie nicht einfach verwenden

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

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

Also muss ich überprüfen, ob die obj Variable ist ein Class Typ, ich nehme an, es wird drin sein C direkt, aber wie kann ich das tun?

Es ist von Vorteil, wenn die Antwort auch eine Möglichkeit bietet, zu überprüfen, ob das Element im Array a ist NSObjectwie die Elemente im Beispielcode, die NSPredicate wäre auch true für die NSObject überprüfen

  • du sagst das Class ist keine obj-C-Klasse, daher ist die Frage etwas verwirrend. Was enthält das Array und womit möchten Sie es vergleichen?

    – Dan Rosenstark

    30. Juni 2011 um 14:31 Uhr

  • +1 Tolle Frage mit nicht offensichtlicher Antwort.

    – Ben Zotto

    30. Juni 2011 um 15:00 Uhr


  • Können Sie mehr darüber sagen, was Sie dann mit dem Array von Klassenobjekten machen wollen? Es gibt eine Antwort auf Ihre eigentliche Frage (Anruf bei @bbum!), aber es könnte weniger praktisch sein, als zu diskutieren, wie Sie sie am besten verwenden können, je nachdem, wie Sie dies tun möchten.

    – Ben Zotto

    30. Juni 2011 um 15:12 Uhr

  • mögliches Duplikat von stackoverflow.com/questions/355312/…

    – Benutzer102008

    22. Juli 2011 um 22:51 Uhr

Benutzer-Avatar
Jo

Um festzustellen, ob ein “Objekt” eine Klasse oder eine Instanz ist, müssen Sie prüfen, ob es sich um eine handelt Meta-Klasse in einem zweistufigen Verfahren. Erster Aufruf object_getClass Überprüfen Sie dann, ob es sich um eine Metaklasse handelt class_isMetaClass. Du wirst brauchen #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));

Beide Class und *id haben das gleiche Struct-Layout (Class isa), können sich daher als Objekte ausgeben und beide Nachrichten empfangen, was es schwierig macht, zu bestimmen, welches was ist. Dies scheint die einzige Möglichkeit zu sein, konsistente Ergebnisse zu erzielen.

BEARBEITEN:

Hier ist Ihr ursprüngliches Beispiel mit dem Scheck:

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];

Und die Ausgabe:

Klasse: NSObject
Klasse: NSWert
Klasse: NSNummer
Klasse: NSPredicate
Instanz: kein Klassenobjekt

  • sehr gute erklärung! und ich kann auch prüfen, ob das Objekt von erbt NSObjectzum Beispiel mit [object_getClass(obj) isSubclassOfClass:[NSObject class]]. tks!

    – Felipe Sabino

    30. Juni 2011 um 16:40 Uhr

  • @Felipe Sabina Ich würde bei class_isMetaClass bleiben, da nicht jedes Objekt garantiert ein NSObject ist, deshalb gibt es das id und ein NSObject Protokoll. Kasse NSProxy das ist eine eigene Root-Klasse developer.apple.com/library/mac/#documentation/Cocoa/Reference/…

    – Jo

    1. Juli 2011 um 12:25 Uhr


  • @Joe Ich wusste nichts über NSProxy, schön, das zu erfahren! aber eigentlich habe ich NSObject nur verwendet, um das Beispiel einfacher zu machen, ich werde es verwenden, um meine Klassen anhand von Kerndaten zu validieren, also muss jede Klasse ein NSManagedObject-Typ sein, dann wird die Regel angewendet. Aber tks für den Hinweis!

    – Felipe Sabino

    1. Juli 2011 um 12:45 Uhr


Benutzer-Avatar
Benutzer102008

Aktualisieren: In iOS 8+ oder OS X 10.10+ können Sie einfach Folgendes tun:

object_isClass(obj)

(Du wirst brauchen #import <objc/runtime.h>.)

  • Ich nehme an, Sie müssen dafür einen ausgefallenen Header importieren, oder?

    – Grady-Spieler

    17. September 2014 um 21:18 Uhr

  • @ user102008 Und gibt es dafür einen Referenzlink?

    – Felipe Sabino

    17. September 2014 um 21:45 Uhr


  • @GradyPlayer: es ist <objc/runtime.h>genau wie alle anderen Antworten auf dieser Seite

    – Benutzer102008

    17. September 2014 um 22:31 Uhr

  • Ich weiß, dass Sie seufzen, aber wir versuchen nur, Ihre Antwort besser zu machen.

    – Grady-Spieler

    17. September 2014 um 22:41 Uhr

  • Verwenden @import ObjectiveC;wenn du sexy bist.

    – Alex Gray

    21. September 2014 um 22:42 Uhr

Joes Antwort ist gut. Eine einfache Alternative, die in den meisten Situationen funktioniert, besteht darin, zu prüfen, ob das Objekt sich selbst als Antwort auf zurückgibt class.

if ([obj class] == obj) { … }

Das funktioniert, weil die NSObject Meta-Klassen-Überschreibungen class und gibt das Klassenobjekt (selbst) zurück – siehe die NSObject-Klassenreferenz. Dies erfordert keine Laufzeitheader, setzt aber voraus, dass die Objekte Unterklassen von sind NSObject und nicht überschreiben -class oder +class und etwas Ungewöhnliches tun.


Mit der Eingabe in der Frage sind die Ergebnisse die gleichen wie bei Joe:

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 (id<NSObject> obj in arr) {

    if ([obj class] == obj) {
        NSLog(@"Class: %@", obj);
    }
    else {
        NSLog(@"Instance: %@", obj);
    }
}

Klasse: NSObject
Klasse: NSWert
Klasse: NSNummer
Klasse: NSPredicate
Instanz: kein Klassenobjekt

  • Dies ist eigentlich ein guter Fang und viel besser lesbar, wenn Sie nur nach Unterklassen von suchen können NSObject

    – Felipe Sabino

    22. April 2015 um 21:12 Uhr

Benutzer-Avatar
Deepak Danduprolu

Wenn Sie überprüfen müssen, ob das Objekt im Array a Class Objekt, dann können Sie überprüfen, ob es auf Klassenmethoden reagiert.

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

Sobald Sie wissen, dass es sich um eine Class Objekt, indem überprüft wird, ob es darauf reagiert isSubclassOfClass: dann kannst du mit auf direkte gleichheit prüfen [NSObject class].

Benutzer-Avatar
Cyprian

Kein Problem, so geht’s:

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

Bearbeiten

Oder Sie können Ihre Klasse an ein Protokoll anpassen: und prüfen, ob obj, das Sie aus dem Array erhalten, diesem Protokoll wie folgt entspricht:

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

Bearbeiten

Oder Sie können überprüfen, ob das, was Sie aus dem Array erhalten, NSObject-kompatibel ist

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

  • Ich hatte auf einen ähnlichen Scheck gehofft isKindOfClass: Methode. Siehst du, wenn obj ist das Ergebnis von [NSObject class]das NSStringFromClass([obj class]) ergibt den String “NSObject”

    – Felipe Sabino

    30. Juni 2011 um 14:41 Uhr

  • Hast Du es versucht? Ich habe es einmal verwendet, als ich ein Objekt vom Typ UIView erhielt. Ich überprüfte, ob es mein benutzerdefiniertes UIView (MyCustomUIView) war und es funktionierte.

    – Cyprian

    30. Juni 2011 um 15:08 Uhr

  • Übrigens können Sie ein Protokoll verwenden. Machen Sie Ihre Klasse konform mit einem Protokoll und prüfen Sie dann, ob das Objekt, das Sie aus dem Array erhalten, ist. entspricht diesem Protokoll. Auf diese Weise erhalten Sie, was Sie wollen. Überprüfen Sie die Antwortbearbeitung

    – Cyprian

    30. Juni 2011 um 15:10 Uhr


  • Bitte überprüfen Sie meine zweite Bearbeitung. Ich denke, das ist, wonach Sie suchen

    – Cyprian

    30. Juni 2011 um 15:17 Uhr

  • Ich muss es auch mit Klassen aus dem Foundation Framework verwenden … also müsste ich Protokolle und Kategorien für diese Klassen erstellen, was ein enormer Aufwand wäre, obwohl es ein netter Hack ist. tks 😉

    – Felipe Sabino

    30. Juni 2011 um 17:08 Uhr

  • Ich hatte auf einen ähnlichen Scheck gehofft isKindOfClass: Methode. Siehst du, wenn obj ist das Ergebnis von [NSObject class]das NSStringFromClass([obj class]) ergibt den String “NSObject”

    – Felipe Sabino

    30. Juni 2011 um 14:41 Uhr

  • Hast Du es versucht? Ich habe es einmal verwendet, als ich ein Objekt vom Typ UIView erhielt. Ich überprüfte, ob es mein benutzerdefiniertes UIView (MyCustomUIView) war und es funktionierte.

    – Cyprian

    30. Juni 2011 um 15:08 Uhr

  • Übrigens können Sie ein Protokoll verwenden. Machen Sie Ihre Klasse konform mit einem Protokoll und prüfen Sie dann, ob das Objekt, das Sie aus dem Array erhalten, ist. entspricht diesem Protokoll. Auf diese Weise erhalten Sie, was Sie wollen. Überprüfen Sie die Antwortbearbeitung

    – Cyprian

    30. Juni 2011 um 15:10 Uhr


  • Bitte überprüfen Sie meine zweite Bearbeitung. Ich denke, das ist, wonach Sie suchen

    – Cyprian

    30. Juni 2011 um 15:17 Uhr

  • Ich muss es auch mit Klassen aus dem Foundation Framework verwenden … also müsste ich Protokolle und Kategorien für diese Klassen erstellen, was ein enormer Aufwand wäre, obwohl es ein netter Hack ist. tks 😉

    – Felipe Sabino

    30. Juni 2011 um 17:08 Uhr

1382920cookie-checkPrüfen Sie, ob das Objekt vom Typ Klasse ist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy