在Objective-C中,当您声明一个实例变量时,您可以检查它是否符合编译时分配的协议,如下所示:
id <MyProtocol> variable;
是否可以在编译时检查分配给变量的对象是否符合两个单独的协议?如:
id <MyProtocol, MyOtherProtocol> variable;
我知道我可以使用conformsToProtocol:
和respondsToSelector
等进行运行时检查(我在实际使用对象之前做的是为了增加安全性),我可以编写自己的setter方法来执行检查,但我想在编译时知道。
答案 0 :(得分:53)
是的,这种语法是正确的。
检查对象是否符合协议的正确方法是:
if ([myObj conformsToProtocol:@protocol(MyProtocol)]) {
//conformance!
}
请注意,这既适用于实例方法,也适用于类方法。
如果由于某些奇怪的原因您无法使用conformsToProtocol:
,您可以下拉到运行时级别:
#import <objc/runtime.h>
Protocol * p = objc_getProtocol("MyProtocol");
if (class_conformsToProtocol([myObj class], p)) {
//conformance!
}
答案 1 :(得分:12)
我认为最好是使用自己的代码:
id <MyProtocol, MyOtherProtocol> variable;
在调用方法之前,检查变量是否响应您要调用的内容:
if ([variable respondsToSelector:@selector(aMethod:)]) {
[variable aMethod:nil];
}
由于Objective-C是一种动态语言,只是声明变量协议无法保证它符合协议。它会在你构建时产生警告。
答案 2 :(得分:3)
您无法始终在编译时检查协议一致性,因为(非限定)类型id
的对象始终是编译器角度的有效对象。例如,
id<P1> p1;
id<P2> p2;
id p0;
// compiler warning: assigning to 'id<P1>' from incompatible type 'id<P2>'
p1 = p2;
// no compiler warning
p0 = p2;
p1 = p0;
话虽这么说,<P1, P2>
会给你警告,以防对象不符合 if 这两个协议,这些协议可以在编译时知道:
id<P1> p1;
id<P2> p2;
id<P1, P2> p12;
id<P1, P2> q12;
id p0;
p12 = p1; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P1>'
p12 = p2; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P2>'
p12 = q12; // no compiler warning
// no compiler warning
p0 = p1;
p12 = p0;