Ios 为什么协议对超类隐藏方法和属性?

Ios 为什么协议对超类隐藏方法和属性?,ios,class,cocoa,cocoa-touch,Ios,Class,Cocoa,Cocoa Touch,考虑这个类:CAEmitterLayer。此类响应属性名称 现在我已经创建了一个名为myMitter的CAEmitterLayer,这个类符合我创建的名为MyProtocol的协议 myMitter类声明如下: for (id <MyProtocol> node in nodes) { [node setName:@"ddd"]; // error here } 标题 #import "MyProtocol.h" @interface MyEmitter : CA

考虑这个类:
CAEmitterLayer
。此类响应属性
名称

现在我已经创建了一个名为
myMitter
CAEmitterLayer
,这个类符合我创建的名为
MyProtocol
的协议

myMitter
类声明如下:

  for (id <MyProtocol> node in nodes) {
    [node setName:@"ddd"]; // error here
  }
标题

#import "MyProtocol.h"

@interface MyEmitter : CAEmitterLayer <MyProtocol>

@end
协议就是这样的:

@protocol MyProtocol <NSObject>

@property (nonatomic, strong) NSString * internalString;

@end
并尝试使用
name
属性,xcode抱怨选择器“name”没有已知的实例方法

事实上,我无法从类
CAEmitterLayer
访问任何属性,即使
myMitter
是该类的子类

我试着这样使用它:

  for (id <MyProtocol> node in nodes) {
    [node setName:@"ddd"]; // error here
  }
for(节点中的id节点){
[节点集名称:@“ddd”];//此处出错
}
显然,该协议对超类隐藏了所有内容。这是为什么?我该如何解决


注意:我必须将合成行添加到类中,否则xcode将无法停止抱怨。

节点的静态类型是
id
。编译器正确地说,该类型没有声明
setName:
方法


只需切换到MyMitter*,它就会工作。

节点的静态类型是
id
。编译器正确地说,该类型没有声明
setName:
方法


只需切换到MyMitter*,它就会工作。

要扩展另一个答案,您将收到一个编译时错误,因为编译器必须按照您告诉它的方式工作

现在,您知道(或者至少希望)在运行时,
node
将成为
myMitter
的一个实例,但编译器没有,因为您已经告诉它,
node
是一个
id

如果您可以让您的程序运行,那么
[node setName://code>将起作用,因为objective-C在运行时找到了正确的选择器

类似地,如果您告诉编译器,
node
myMitter
的一个实例,但在运行时它是另一个对象类(由于代码中其他地方的错误),那么它将编译,但可能在运行时引发异常

所以你可以说-

 for (MyEmitter *node in nodes) {
    [node setName:@"ddd"]; 
 }
或者,如果你不需要做任何特定于你的子类的事情,你甚至可以说

 for (CAEmitterLayer *node in nodes) {
    [node setName:@"ddd"]; 
 }

要扩展另一个答案,您将收到一个编译时错误,因为编译器必须根据您告诉它的内容工作

现在,您知道(或者至少希望)在运行时,
node
将成为
myMitter
的一个实例,但编译器没有,因为您已经告诉它,
node
是一个
id

如果您可以让您的程序运行,那么
[node setName://code>将起作用,因为objective-C在运行时找到了正确的选择器

类似地,如果您告诉编译器,
node
myMitter
的一个实例,但在运行时它是另一个对象类(由于代码中其他地方的错误),那么它将编译,但可能在运行时引发异常

所以你可以说-

 for (MyEmitter *node in nodes) {
    [node setName:@"ddd"]; 
 }
或者,如果你不需要做任何特定于你的子类的事情,你甚至可以说

 for (CAEmitterLayer *node in nodes) {
    [node setName:@"ddd"]; 
 }

展示你是如何使用它的,它是否真的在你的代码行中使用了
obj
?您可以访问
internalString
而不出错吗?是的,协议属性总是需要被综合(或重新定义)。。。。是的,我可以访问internalString。我无法访问CAEmitterLayer的任何属性…演示您如何尝试使用它,它是否确实在您的代码行中使用了
obj
?您可以访问
internalString
而不出错吗?是的,协议属性总是需要被综合(或重新定义)。。。。是的,我可以访问internalString。我不能访问CAEmitterLayer的任何属性…当然,为什么。这就是静态型安全的意义。当然,为什么。这就是静态类型安全的全部内容。