Objective-C class_conformsToProtocol()bug?

Ric*_*III 11 iphone protocols class objective-c

我在我的iPhone Objective-C应用程序中遇到了一些奇怪的行为.

我正在使用一些代码来测试一个对象:

if (!class_conformsToProtocol([someVar someFunctionThatReturnsAClass], @protocol(MyProtocol)))
     [NSException raise:@"Invalid Argument" format:@"The variables returned by 'someFunctionThatReturnsAClass' Must conform to the 'myProtocol' protocol in this case."];
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当我有一个看起来像这样的课:

@interface BaseClass : NSObject<MyProtocol>

...

@end

@interface SubClass : BaseClass

...

@end
Run Code Online (Sandbox Code Playgroud)

当我调用这个片段时class_conformsToProtocol([SubClass class], @protocol(MyProtocol)),它会返回NO.

此外,此代码失败:

class_conformsToProtocol([NSString class], @protocol(NSObject)); // also returns NO
Run Code Online (Sandbox Code Playgroud)

这段代码返回时YES:

[NSString conformsToProtocol:@protocol(NSObject)];
Run Code Online (Sandbox Code Playgroud)

我在文档中遗漏了什么吗?或者这是某种错误?(如果重要的话,我在iOS 4.2上).

Lil*_*ard 15

如果这里有一个错误,那就在文档中.

根据源,class_conformsToProtocol()使用class_copyProtocolList()然后针对参数测试每个得到的协议.class_copyProtocolList()记录为仅返回给定类采用的协议,但不记录超类采用的协议.class_conformsToProtocol()因此,只测试给定的类是否采用协议而不是超类.

文档错误是class_conformsToProtocol()不会说明此行为.但是,文档确实说明您通常不应该使用该函数,而是使用NSObjectconformsToProtocol:方法.


Jac*_*kin 5

使用NSObjectconformsToProtocol:方法.

这是我尝试过的一个实验:

@protocol MyProtocol

- (void) doSomething;

@end

@interface MyClass : NSObject<MyProtocol>
{
}

@end

@implementation MyClass

- (void) doSomething { 
}

@end

@interface MyOtherClass : MyClass
{

}

@end

@implementation MyOtherClass

- (void) doSomething {
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    MyClass *obj_one = [MyClass new];
    BOOL one_conforms = [obj_one conformsToProtocol:@protocol(MyProtocol)];

    MyOtherClass *obj_two = [MyOtherClass new];
    BOOL two_conforms  = [obj_two conformsToProtocol:@protocol(MyProtocol)];
    NSLog(@"obj_one conformsToProtocol: %d", one_conforms);
    NSLog(@"obj_two conformsToProtocol: %d", two_conforms);

    [pool drain];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

obj_one conformsToProtocol: 1
obj_two conformsToProtocol: 1
Run Code Online (Sandbox Code Playgroud)

鉴于:

MyOtherClass *obj_two = [MyOtherClass new];
BOOL conforms_two = class_conformsToProtocol([obj_two class], @protocol(MyProtocol));
NSLog(@"obj_two conformsToProtocol: %d", conforms_two);
Run Code Online (Sandbox Code Playgroud)

输出:

obj_two conformsToProtocol: 0
Run Code Online (Sandbox Code Playgroud)

判决:

这是一个bug class_conformsToProtocol,使用conformsToProtocol:方法NSObject

不像class_conformsToProtocol,NSObject's conformsToProtocol:方法也会检查超类.