将类别方法添加到NSObject,但是因为它在我调用它时不在<NSObject>协议中而得到警告

zek*_*kel 4 iphone cocoa-touch protocols objective-c categories

(我发现了一些 讨论这个想法的问题,但我没有找到解决问题的方法.)

我将此便捷方法添加为NSObject的类别.(我添加了其他方法,所以即使你不同意这种特殊的便利方法,我仍然对答案感兴趣.)

@implementation NSObject (MyCategory)
- (void)performInvocationOnMainThread:(NSInvocation *)invocation waitUntilDone:(BOOL)waitForMainThread;
@end
Run Code Online (Sandbox Code Playgroud)

然后我有一个我定义的协议:

@protocol MyDelegateProtocol <NSObject>
- (void)myDelegateProtocolMethod;
@end
Run Code Online (Sandbox Code Playgroud)

然后我将委托声明为我的类的属性,实现所述协议.

@property (nonatomic, assign) id <MyDelegateProtocol> delegate;
Run Code Online (Sandbox Code Playgroud)

但是当我尝试调用NSObject方法时,我在我的类别中添加了这样的内容

NSInvocation *invocation = [self.delegate invocationForSelector:@selector(someSelector:withArg:)];
Run Code Online (Sandbox Code Playgroud)

我收到了这个警告

'-performInvocationOnMainThread:waitUntilDone:' not found in protocol(s)
Run Code Online (Sandbox Code Playgroud)

如果我将我的代表投下,(NSObject *)那么我就不会收到警告.我究竟做错了什么?我似乎不能(或应该)在不创建"子协议"的情况下向现有协议添加方法,并从此开始使用它.(考虑到在NSObject中添加方法的意义,哪种方式失败了.)

NSInvocation *invocation = [(NSObject *)self.delegate invocationForSelector:@selector(someSelector:withArg:)];
Run Code Online (Sandbox Code Playgroud)

Bol*_*ock 5

您的类别扩展了NSObject ,而不是NSObject 协议.虽然该类现在具有该方法,但它未被定义为协议的一部分,因此警告.

这就是为什么对NSObject *指针类型进行类型转换的原因; 你正在转换为NSObject类类型,而不是类似于id<NSObject>符合NSObject协议的任意Objective-C对象.

您必须制作扩展NSObject协议的中间协议(或"子协议"):

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

然后让你的委托协议扩展那个:

@protocol MyDelegateProtocol <ExtendedNSObject>
- (void)myDelegateProtocolMethod;
@end
Run Code Online (Sandbox Code Playgroud)

如果我没有错,你可以保留现有的NSObject (MyCategory)实施,他们会一起玩得很好.