Adding a category method to NSObject but receiving warnings because it is not in the <NSObject> protocol when I call it

(I found some questions discussing this idea, but I did not see a solution for my problem.)

I added this convenience method as a category in NSObject. (I added other methods, so I am still interested in the answer, even if you do not agree with this particular convenience method.)

@implementation NSObject (MyCategory) - (void)performInvocationOnMainThread:(NSInvocation *)invocation waitUntilDone:(BOOL)waitForMainThread; @end 

Then I have a protocol that I defined:

 @protocol MyDelegateProtocol <NSObject> - (void)myDelegateProtocolMethod; @end 

Then I declare the delegate as a property of my class that implements the specified protocol.

 @property (nonatomic, assign) id <MyDelegateProtocol> delegate; 

But when I try to call the NSObject method, I added to my category like this:

 NSInvocation *invocation = [self.delegate invocationForSelector:@selector(someSelector:withArg:)]; 

I get this warning

 '-performInvocationOnMainThread:waitUntilDone:' not found in protocol(s) 

If I pass my delegate as (NSObject *) , then I will not receive a warning. What am I doing wrong? It seems I could not (or should I?) Add methods to an existing protocol without creating an โ€œauxiliary protocolโ€ and use it from now on. (What kind of hit is the meaning of adding methods to NSObject).

 NSInvocation *invocation = [(NSObject *)self.delegate invocationForSelector:@selector(someSelector:withArg:)]; 
+4
source share
2 answers

Your category extends the NSObject class , not the NSObject protocol . Although the class now has this method, it is not defined as part of the protocol, so there is a warning.

Why does casting to a pointer type NSObject * ; you are executing an NSObject class NSObject , not something like id<NSObject> , which means an arbitrary Objective-C object that conforms to the NSObject protocol.

You will need to make an intermediate protocol (or "auxiliary protocol") that extends the NSObject protocol:

 @protocol ExtendedNSObject <NSObject> - (void)performInvocationOnMainThread:(NSInvocation *)invocation waitUntilDone:(BOOL)waitForMainThread; @end 

Then pass your delegate protocol instead:

 @protocol MyDelegateProtocol <ExtendedNSObject> - (void)myDelegateProtocolMethod; @end 

If I'm not mistaken, you can keep the existing implementation of NSObject (MyCategory) , and they will play well together.

+5
source

when pass / expect this type, qualify it like this:

 - (void)race:(NSObject<MyDelegateProtocol>*)arg; 
+3
source

All Articles