您正在调用此代码:
if ([refreshViewControllerDelegate conformsToProtocol:@protocol(ReloadViewControllerDelegate)])
但这refreshViewControllerDelegate
是不是:
id refreshViewControllerDelegate;
conformsToProtocol
检查对象是否声明它符合协议,而您的则不。如果要指定对协议的符合性,您需要:
id<ReloadViewControllerDelegate> refreshViewControllerDelegate;
编辑
好的,关于performSelectorOnMainThread
问题...该方法在 NSThread 的类别中提供,并且未在 NSObject 协议中声明。所以,如果你想调用它,那么你需要将你的类型声明为 NSObject,它符合你的协议。
NSObject<ReloadViewControllerDelegate> refreshViewControllerDelegate;
编辑
好的,看起来这不是一个关于使用协议的简单问题,而是一个完整的教程。由于 SO 不是这样的地方,我将尝试给出一个简短的...
协议是一个接口声明。
@protocol ReloadChatViewControllerDelegate <NSObject>
- (void)refreshViewController:(NSString *)result;
@end
那就是说镇上有一个新协议,名称ReloadChatViewControllerDelegate
和它也符合NSObject
协议。任何采用新协议的类都必须提供refreshViewController
. 您可以通过放入一个@optional
部分来使协议方法成为可选方法。
@protocol ReloadChatViewControllerDelegate <NSObject>
- (void)refreshViewController:(NSString *)result;
@optional
- (void)optRefresh;
@end
现在,让我们将协议的采用留到以后。假设您正在编写通用代码,并且您只想知道给定的对象是否符合协议,如果符合,请在其上调用方法。就像是...
@interface Bar : NSObject
@property (nonatomic, weak) NSObject<ReloadChatViewControllerDelegate> *refreshViewControllerDelegate;
- (void)blarg;
@end
现在,Bar 类提供了一个委托属性,以便它可以提供一些对象来帮助它完成一些工作。但是,该委托对象必须至少是NSObject
, 并且符合ReloadChatViewControllerDelegate
协议。
现在,ObjC(和 C)是相当宽松的,所以你可以强制一个对象是你想要的任何类型,但是你应该得到你得到的崩溃。现在,当blarg
被调用时,会通知委托人做一些工作。
由于委托的属性类型已经表明它符合给定的协议,因此无需检查是否符合。我们可以调用委托方法。请注意,我们必须查看对象是否实现了任何可选的协议方法。
@implementation Bar
@synthesize refreshViewControllerDelegate = _refreshViewControllerDelegate;
- (void)blarg {
// Do something, then invoke the delegate
[self.refreshViewControllerDelegate
performSelectorOnMainThread:@selector(refreshViewController:)
withObject:@"YES"
waitUntilDone:NO];
if ([self.refreshViewControllerDelegate respondsToSelector:@selector(optRefresh)]) {
[self.refreshViewControllerDelegate optRefresh];
}
}
@end
但是,如果您想成为通用的,并接受任何对象作为委托(也许您想让委托符合某个给定的协议是可选的),那么您可以接受一个普通的id
,然后检查它是否符合。在这种情况下,您可以将您的委托声明为一个 id(或其他类型)。
@property (nonatomic, weak) id refreshViewControllerDelegate;
现在,在您的代码中,您需要检查一致性。
- (void)blarg {
// Do something, then invoke the delegate
if ([self.refreshViewControllerDelegate
conformsToProtocol:@protocol(ReloadChatViewControllerDelegate)]) {
[self.refreshViewControllerDelegate
performSelectorOnMainThread:@selector(refreshViewController:)
withObject:@"YES" waitUntilDone:NO];
if ([self.refreshViewControllerDelegate
respondsToSelector:@selector(optRefresh)]) {
[self.refreshViewControllerDelegate optRefresh];
}
}
}
好的,现在您已经定义了一个协议,并且您有调用该协议上的方法的代码。两个警告。
首先,必须将委托设置为一个对象。 nil
将响应false
任何方法,因此它当然不会遵守,也不会在发送任何消息时做任何事情。
其次,您必须确保您的委托声明符合协议。仅仅实现这些方法是不符合的。如果一个类没有明确指定它符合协议,那么conformsToProtocol
即使它实现了协议的方法,它也会返回 false。
所以,让我们指定一些符合协议的类作为我们的委托。
@interface Foo : NSObject<ReloadChatViewControllerDelegate>
- (void)refreshViewController:(NSString *)result;
@end
@implementation Foo
- (void)refreshViewController:(NSString *)result {
NSLog(@"Look, ma, I'm refreshed with %@", result);
}
@end
它符合协议,提供强制方法的实现,省略可选方法。
现在,如果你运行这段代码,你应该会看到这段奇妙的代码。
Foo *foo = [[Foo alloc] init];
Bar *bar = [[Bar alloc] init];
bar.refreshViewControllerDelegate = foo;
[bar blarg];