(I found some questions discussing the idea, but I didn't see a solution for my problem.)
I added this convenience method as a category to NSObject. (I've added other methods, so I'm still interested in an answer even if you disagree with this particular convenience method.)
@implementation NSObject (MyCategory)
- (void)performInvocationOnMainThread:(NSInvocation *)invocation waitUntilDone:(BOOL)waitForMainThread;
@end
Then I have a protocol I defined:
@protocol MyDelegateProtocol <NSObject>
- (void)myDelegateProtocolMethod;
@end
Then I declare the delegate as a property of my class that implements said protocol.
@property (nonatomic, assign) id <MyDelegateProtocol> delegate;
But when I try to call the NSObject method I added in my category like so
NSInvocation *invocation = [self.delegate invocationForSelector:@selector(someSelector:withArg:)];
I get this warning
'-performInvocationOnMainThread:waitUntilDone:' not found in protocol(s)
If I cast my delegate as (NSObject *)
then I don't get the warning. What am I doing wrong? It didn't seem like I could (or should?) add methods to an existing protocol without creating a "sub protocol" and using it from then on. (Which kind of defeats the point of adding methods to NSObject in mind.)
NSInvocation *invocation = [(NSObject *)self.delegate invocationForSelector:@selector(someSelector:withArg:)];
Your category extends the NSObject
class, not the NSObject
protocol. While the class now has the method, it's not defined as part of the protocol, hence the warning.
That's why typecasting to the NSObject *
pointer type works; you're casting to the NSObject
class type, rather than something like id<NSObject>
which means an arbitrary Objective-C object that conforms to the NSObject
protocol.
You'll have to make an intermediate protocol (or "sub protocol") that extends the NSObject
protocol:
@protocol ExtendedNSObject <NSObject>
- (void)performInvocationOnMainThread:(NSInvocation *)invocation waitUntilDone:(BOOL)waitForMainThread;
@end
Then have your delegate protocol extend that one instead:
@protocol MyDelegateProtocol <ExtendedNSObject>
- (void)myDelegateProtocolMethod;
@end
If I'm not wrong, you can keep the existing NSObject (MyCategory)
implementation, and they'll play nice together.
when pass/expect this type, qualify it like so:
- (void)race:(NSObject<MyDelegateProtocol>*)arg;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With