3

私は iPhone の Objective-C で作業しており、「クラス」が「NSObject」から継承されているかどうかを知る必要があります。

NSObject セレクターに応答するかどうかを確認してみました。

bool success = [myClass respondsToSelector:@selector(class)];

しかし、何が起こったのか推測できます...「respondsToSelector:」にも応答しなかったため、「doesNotRecognizeSelector: を実装していません:」例外がスローされます。

その例外をキャッチしようとしましたが、@try-@catch ではキャッチできないようです。

何か案は?

4

4 に答える 4

7

Objective-C ランタイムに直接移動します。

#import <objc/runtime.h>

/* originally posted version — works because eventually class_getSuperclass(class)
returns nil, and class_getSuperclass(nil) does so also. */
BOOL classDescendsFromClass(Class classA, Class classB)
{
    while(1)
    {
        if(classA == classB) return YES;
        id superClass = class_getSuperclass(classA);
        if(classA == superClass) return (superClass == classB);
        classA = superClass;
    }
}

/* shorter version; exits straight after classA turns into nil */
BOOL classDescendsFromClassShorter(Class classA, Class classB)
{
    while(classA)
    {
        if(classA == classB) return YES;
        classA = class_getSuperclass(classA);
    }

    return NO;
}
...

if(classDescendsFromClass(classToTest->isa, [NSObject class]) ...

class_getSuperclass各クラスのメタクラスのインスタンスは 1 つしかないため、Objective-C ランタイムでポインターによってメタクラスを比較しても安全です。isa ポインターは、構造体 objc_object に確実にある唯一のものです。

編集: さらに、iPhone シミュレーターには既知のバグがあり、一部の例外が try/catch ブロックによってキャッチされません。私はそれらをバグとして Apple に報告し、私のものは重複していると言われたので、彼らは確実に認識しています。コードを実際のデバイスまたはシミュレーターで試しましたか?

EDIT2:この会話の他の場所で与えられたより広い文脈から、次のようなものがよりスマートかもしれません:

#import <objc/runtime.h>

BOOL classRespondsToSelector(Class classA, SEL selector)
{
    return class_getInstanceMethod(classA, selector) ? YES : NO;
}

....
if(classRespondsToSelector(instance->isa, @selector(respondsToSelector:))
{
     // great, we've got something that responds to respondsToSelector:; do the
     // rest of our querying through there
}
于 2010-11-22T23:57:10.333 に答える
4

isKindOfClass:メソッドとメソッドを使用してisMemberOfClass:、クラスが別のクラスのサブクラスであるか、特定のクラスであるかを判断できます。

于 2010-11-22T23:31:21.093 に答える
1

respondsToSelector:はそれ自体が NSObject 定義のセレクタであるため、使用できません。Objective-C の内部に深く入り込まずにこれを行う方法があるとは思えません。

NSObject の子孫ではないオブジェクトがある理由をお聞きしてもよろしいですか? Apple は、正当な理由により、それらを作成しようとしないことを強くお勧めします。

于 2010-11-22T23:38:33.140 に答える
-3

クラス 'Class' は NSObject から継承されません。つまり、NSObject で定義されたメソッド ( や などisKindOfClass)respondsToSelectorは使用できません。

そもそもそれで何をしようとしているのですか?

于 2010-11-22T23:38:59.023 に答える