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

时间:2011-05-16 20:58:05

标签: iphone objective-c cocoa-touch protocols categories

(我发现some questions正在讨论这个想法,但我没有找到解决问题的方法。)

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

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

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

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

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

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

但是当我尝试调用NSObject方法时,我添加了类似的

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

我收到此警告

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

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

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

2 个答案:

答案 0 :(得分:5)

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

这就是为NSObject *指针类型进行类型转换的原因;你正在转换为NSObject类类型,而不是像id<NSObject>这样的东西,这意味着一个符合NSObject协议的任意Objective-C对象。

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

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

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

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

如果我没有错误,您可以保留现有的NSObject (MyCategory)实施,并且它们会很好地协同工作。

答案 1 :(得分:3)

当传递/期望这种类型时,如此符合条件:

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