iphone - performSelector:withObject:afterDelay:'在协议中找不到?

时间:2010-11-28 02:59:08

标签: iphone objective-c

我在课堂上有这个

[delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];

我有这个错误

  

警告:   '-performSelector:withObject:afterDelay:'   在协议中找不到

我无法弄清楚可能出现的问题。

任何线索?

感谢。

5 个答案:

答案 0 :(得分:30)

您的问题是您已将委托实例变量声明为:

id<SomeProtocol> delegate;

右?嗯,这意味着编译时检查器只会在<SomeProtocol>协议中查找方法。但是,performSelector:withObject:afterDelay:上已声明NSObject。这意味着您应该将ivar声明为:

NSObject<SomeProtocol> * delegate;

这表示它必须是符合NSObject的{​​{1}},而不是符合<SomeProtocol>的任何对象。这应该摆脱你的警告,你不必做任何演员。

答案 1 :(得分:3)

首先尝试将委托转换为其类'type,然后调用performSelector:withObject:afterDelay

[(SomeClass *) delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];

假设您的delegate类型为id,您需要告诉运行时该对象实际上确实从NSObject继承(其中performSelector:withObject:afterDelay:方法已定义通过将其转换为类的类型。

答案 2 :(得分:3)

尽管Dave提出的NSObject *演员会工作,但是有一种更清晰的替代方式可以让人们按照他们的预期使用协议 - 你可以让协议本身声明它支持NSObject协议。

NSObject不仅是一个实现,还是一个包含所有performSelector:方法变体的协议。因此,您可以在协议中声明您支持NSObject,就像您支持协议的任何其他类一样:

@protocol MyProtocol <NSObject>

编译器警告将消失(假设您已导入协议定义)。

请注意,这确实意味着前进任何声明支持您的协议的人几乎必须是NSObject或继承许多方法。但是,由于实际考虑,iPhone编程中使用的所有类都来自NSObject,所以这通常不是问题。

编辑:

事实证明-performSelector:withObject:afterDelay:不在NSObject协议中(没有延迟的协议)。因为对于每个使用你的协议的人来说,如果他们只能使用id引用协议类型,它仍然会更好,我仍然会使用协议来解决这个问题 - 但是你必须自己声明NSObject协议的扩展。因此,在文件的标题中,您可以添加以下内容:

@protocol MyProtocolNSObjectExtras <NSObject>
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
@end

@protocol MyProtocol <NSObjectExtras>
....
@end

然后你获得了我之前描述的所有相同的好处。

答案 3 :(得分:2)

您需要将委托对象强制转换为您正在使用的实际类,以便拥有这些方法。看到委托只能显示协议中定义的方法。 performSelector:withObject:不是协议中定义的方法。

[(CLASS*)delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];

答案 4 :(得分:1)

[NSTimer scheduledTimerWithTimeInterval:2
    target:self 
    selector:@selector(doStuff) 
    userInfo:nil 
    repeats:NO];

尝试假设您只想要一个计时器