【问题标题】:Why can't a variable typed as id<someProtocol> receive a parameter of id<otherProtocol> even if 'otherProtocol' conforms to 'someProtocol'?为什么类型为 id<someProtocol> 的变量不能接收 id<otherProtocol> 的参数,即使“otherProtocol”符合“someProtocol”?
【发布时间】:2012-04-05 21:22:21
【问题描述】:

假设我有两个协议:

@protocol A
@end

@protocol B <A> // Protocol B conforms to protocol A.
@end

还有两个变量:

id<A> myVar = nil;

id<B> otherVar = //correctly initialized to some class that conforms to <B>;

那么,为什么我不能将 'otherVar' 分配给 'myVar'?

myVar = otherVar; //Warning, sending id<B> to parameter of incompatible type id<A>

谢谢!

【问题讨论】:

  • 你试过转换变量吗?
  • 我无法重现这个。协议是否在单独的文件中?您要导入哪些标头以及在哪里导入?
  • 是的,协议在单独的文件中。问题在于文件的可见性。当我应该导入文件时,我使用了前向声明。

标签: objective-c ios macos polymorphism protocols


【解决方案1】:

协议的 (B) 声明(不仅仅是它的前向声明)是否可见?声明是否在myVar = otherVar; 之前?

当申报顺序正确时,clang没有抱怨。

举例说明:

@protocol A
@end

@protocol B; // << forward B

void fn() {
    id<A> myVar = nil;
    id<B> otherVar = nil;
    myVar = otherVar; // << warning
}

// declaration follows use, or is not visible:    
@protocol B <A>
@end

而正确排序的版本不会产生警告:

@protocol A
@end

@protocol B <A>
@end

void fn() {
    id<A> myVar = nil;
    id<B> otherVar = nil;
    myVar = otherVar;
}

【讨论】:

  • 谢谢贾斯汀!你是对的,问题在于协议的可见性。
【解决方案2】:

检查它是否为conformsToProtocol(),如果是,则像这样投射它

myVar = (id <A>)otherVar;

类似的问题可以在Cast an instance of a class to a @protocol in Objective-C查看

【讨论】:

    猜你喜欢
    • 2022-11-27
    • 2014-01-27
    • 2015-08-01
    • 1970-01-01
    • 2022-07-11
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多