Objective c 如何将类对象强制转换为协议一致性

Objective c 如何将类对象强制转换为协议一致性,objective-c,ios,Objective C,Ios,我试图将一个类对象强制转换为某个协议,该协议定义了该类实现的类方法(+) 我知道如何使用(id)实现这一点,但我似乎无法找到类对象的正确方法 基本情况如下 我有一个协议: @protocol Protocol <NSObject> + (id)classMethod:(id)arg; @end @协议 +(id)classMethod:(id)arg; @结束 然后,我有一个函数,它接受一个类对象,它知道这个类对象有时根据另一个参数符合协议(这显然是非常简化的): -(id)so

我试图将一个类对象强制转换为某个协议,该协议定义了该类实现的类方法(+)

我知道如何使用(id)实现这一点,但我似乎无法找到类对象的正确方法

基本情况如下

我有一个协议:

@protocol Protocol <NSObject>
+ (id)classMethod:(id)arg;
@end
@协议
+(id)classMethod:(id)arg;
@结束
然后,我有一个函数,它接受一个类对象,它知道这个类对象有时根据另一个参数符合协议(这显然是非常简化的):

-(id)someMethodWithClass:(Class)cls和UseArg:(BOOL)arg
{
id实例;
如果(arg!=nil){
实例=[(类)cls classMethod:arg];
}
}
现在我没有收到任何警告,我觉得这是对的。(在任何情况下,我都不会看到任何错误,因为我可以保证如果arg!=nil,则类符合。)


然而,我没有在Xcode中获得自动完成功能,这让我怀疑这是否是正确的方法。有什么想法吗?(请注意,我对实例id不感兴趣)

如果要确定
cls
是否符合特定协议(并假设
classMethod:
是该协议的必需类方法),您可以简单地:

- (id)someMethodWithClass:(Class)cls andUseArg:(BOOL)arg
{
    id instance;
    if ([cls conformsToProtocol:@protocol(Protocol)]) {
        instance = [cls classMethod:arg];
    }

    return instance;
}
或者,只需查看它是否响应特定的类方法选择器:

- (id)someMethodWithClass:(Class)cls andUseArg:(BOOL)arg
{
    id instance;
    if ([cls respondsToSelector:@selector(classMethod:)]) {
        instance = [cls classMethod:arg];
    }

    return instance;
}

您不应该将其强制转换为协议,而应该更改类本身以仅符合该协议(例如.h中的
@interface MyClass
,或
@interface MyClass()
在.m.中,编译器将允许使用该协议的方法自动完成,并且不需要强制转换。通常,修复对象或类定义比强制转换要好。此外,通过定义类以符合特定协议,如果您未能实现某些所需的协议。谢谢,但可能我不够清楚。cls是一个类对象(类型为class的对象),而不是我定义的类(换句话说,它作为[SomeClass]传入)。在这个简单的例子中,如果arg!=nil,那么我知道cls是一个实现协议的类。我只想让Xcode意识到这一点。我很惊讶你在这里没有收到编译器警告,因为首先你将BOOL与指针进行比较(传递
nil
arg
与传递
FALSE
相同),其次,您没有从该方法返回任何内容。可能您使用的是未生成警告的较旧版本的编译器,或者您已关闭了一些警告。如果
arg
id
或指针,则您的构造是有意义的,但如果
BOOL
,则没有。此外,您也没有返回
instance
。当我编译您的代码时,我会收到这两个方面的警告。这些代码显然不是全部函数,只是前几行。arg本来是id,但我复制错误。我唯一关心的是类强制转换。嗨,Rob,我知道cls已经符合给定的协议(这是函数的一个先决条件,如果arg不是nil,那么cls将符合)。我想要的是一种方法,让那些在没有明确测试一致性的情况下阅读我的代码的人明白这一点(如我上面链接的问题)我真的很好奇类是否是有效的强制转换,如果不是,有效的类会是什么be@sapi
是有效的,尽管不必要且不典型。但如果您想执行此强制转换,此语法是合适的。顺便说一下,您提到的问题确实明确测试了一致性(这是很好的,防御性编程),并仅将指针强制转换到协议,以防止编译器发出警告。恕我直言,这两个条件在这里都不成立。您要求未来的开发人员查看实现的详细信息,以推断应该传递什么类,但您无法优雅地处理他们意外传递错误cl的情况ass.我会支持
conformsToProtocol
respondsToSelector
(无论是与您的cast一起使用还是代替)。恕我直言,我不同意这一点。如果我要为函数指定一个先决条件,那么我不会在运行时测试它(断言除外)。如果不满足前提条件,则此函数或应用程序无法执行任何合理的操作,因此协议检查的开销没有用处。@sapi公平。我们同意在这一点上存在分歧。:)
- (id)someMethodWithClass:(Class)cls andUseArg:(BOOL)arg
{
    id instance;
    if ([cls respondsToSelector:@selector(classMethod:)]) {
        instance = [cls classMethod:arg];
    }

    return instance;
}