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

时间:2015-03-15 19:41:45

标签: ios class cocoa cocoa-touch

考虑这个课程:CAEmitterLayer。此类响应属性name

现在我创建了一个名为CAEmitterLayer的{​​{1}},这个类符合我创建的名为MyEmitter的协议。

MyProtocol类声明是这样的:

标题

MyEmitter

实施

#import "MyProtocol.h"

@interface MyEmitter : CAEmitterLayer <MyProtocol>

@end

并且协议就是这样:

#import "MyEmitter.h"

@implementation MyEmitter

@synthesize internalString = _internalString;

@end

这就是问题所在。如果我像这样创建一个新对象

@protocol MyProtocol <NSObject>

@property (nonatomic, strong) NSString * internalString;

@end

并尝试使用MyEmitter *obj = [[MyEmitter alloc] init]; 属性,xcode抱怨没有已知的选择器'name'实例方法

实际上我无法访问类name中的任何属性,即使CAEmitterLayer是该类的子类。

我试图像这样使用它:

MyEmitter

显然协议隐藏了超类中的所有内容。为什么这样,我该如何解决?

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

2 个答案:

答案 0 :(得分:4)

node的静态类型为id <MyProtocol>。编译器正确地说这种类型没有声明setName:方法。

只需切换到MyEmitter *即可。

答案 1 :(得分:2)

要扩展另一个答案,您收到编译时错误,因为编译器必须按照您所说的那样工作。

现在,您知道(或者至少希望)node在运行时将成为MyEmitter的实例,但编译器没有,因为您告诉它node 1}}是id <MyProtocol>

如果你可以让程序运行,那么[node setName:]就可以了,因为objective-C在运行时找到了正确的选择器。

同样如果你告诉编译器nodeMyEmitter的一个实例,但在运行时它是一个不同的对象类(由于你的代码中的其他地方出现了错误)然后它会编译但是可能会在运行时抛出异常。

所以你可以说 -

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

或者,如果您不需要执行特定于您的子类的任何操作,您甚至可以说

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