开发者

iphone - performSelector:withObject:afterDelay:' not found in protocol(s)?

I have this inside a class

[delegate p开发者_如何学运维erformSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];

and I am having this error

warning: '-performSelector:withObject:afterDelay:' not found in protocol(s)

I cannot figure out what may be wrong.

any clues?

thanks.


Your problem is that you've declared your delegate instance variable as:

id<SomeProtocol> delegate;

Right? Well, that means that the compile-time checker is only going to look for methods in the <SomeProtocol> protocol. However, performSelector:withObject:afterDelay: is declared on NSObject. This means that you should declare the ivar as:

NSObject<SomeProtocol> * delegate;

This is saying that it must be an NSObject that conforms to <SomeProtocol>, as opposed to any object that conforms to <SomeProtocol>. This should get rid of your warning, and you don't have to do any casting.


Try casting the delegate to its class' type first, then invoke performSelector:withObject:afterDelay:

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

Assuming that your delegate is of type id, you need to tell the runtime that the object in fact does inherit from NSObject (where the performSelector:withObject:afterDelay: method is defined) by casting it to it's class' type.


Although the NSObject * cast Dave brought up will work, there's a cleaner alternate way that lets people use protocols as they would expect - you can have the protocol itself declare it supports the NSObject protocol.

NSObject is not just an implementation but also a protocol that includes all of the performSelector: method variants. So you can simply declare in your protocol that you support NSObject like you would any other class supporting a protocol:

@protocol MyProtocol <NSObject>

And the compiler warnings will vanish (assuming you have imported the protocol definition).

Note that this does mean going forward anyone that declares support of your protocol would pretty much have to be an NSObject or inherit a lot of methods. But all classes used in iPhone programming are derived from NSObject due to practical considerations, so that's generally not an issue.

EDIT:

It turns out the -performSelector:withObject:afterDelay: is not in the NSObject protocol (the ones without the delay are). Because it's still nicer to everyone using your protocol if they can just use id to reference a protocol type, I'd still use a protocol to solve this - but you'd have to declare an extension to the NSObject protocol yourself. So in the header for your file you could add something like:

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

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

Then you get all the same benefits as I described previously.


You need to cast the delegate object to the actual class you are working in order to have the methods. Seen the delegate only can only show the methods defined in the protocol. performSelector:withObject: is not a method defined in the protocol.

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


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

Try that assuming you just want a timer

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜