(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
NSObjectclass, not theNSObjectprotocol. 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 theNSObjectclass type, rather than something likeid<NSObject>which means an arbitrary Objective-C object that conforms to theNSObjectprotocol.You’ll have to make an intermediate protocol (or “sub protocol”) that extends the
NSObjectprotocol:Then have your delegate protocol extend that one instead:
If I’m not wrong, you can keep the existing
NSObject (MyCategory)implementation, and they’ll play nice together.