如何在AppDelegate iPhone应用程序中使用@protocol?

我在5屏幕的iPhone应用程序工作。 我想刷新UITabBarController中第四屏幕的值。 我已经在AppDelegate中添加@protocol,但它不是调用。 这是我第一次使用@protocol可以请你帮我解决这个问题,

AppDelegate.h中

@protocol ReloadViewControllerDelegate <NSObject> -(void) refreshViewController:(NSString *)result; @end id refreshViewControllerDelegate; @property (nonatomic, retain) id refreshViewControllerDelegate; 

我已经综合了

AppDelegare.m

 @synthesize refreshViewControllerDelegate; if ([refreshViewControllerDelegate conformsToProtocol:@protocol(ReloadViewControllerDelegate)]) { [refreshViewControllerDelegate performSelectorOnMainThread:@selector(refreshViewController:) withObject:@"YES" waitUntilDone:NO]; }// Control not come inside of if Condition.... From here i want to update the fourthViewController.. 

但是control not go inside of the if condition 。 你能指导我在哪里做错了吗?

在我的第四个ViewController.h

 #import "AppDelegate" @interface fourthViewController : UIViewController <ReloadViewControllerDelegate> 

在我的第四个ViewController.m

 -(void) refreshViewController:(NSString *)result { NSLog(@"Result : %@", result); } 

任何人都可以请帮我做这个? 提前致谢。

你正在调用这个代码:

 if ([refreshViewControllerDelegate conformsToProtocol:@protocol(ReloadViewControllerDelegate)]) 

但是refreshViewControllerDelegate是这样的:

 id refreshViewControllerDelegate; 

conformsToProtocol检查对象是否声明它符合协议,而不是你的协议。 如果您想要指定符合协议,您需要:

 id<ReloadViewControllerDelegate> refreshViewControllerDelegate; 

编辑

OK,关于performSelectorOnMainThread问题…该方法在NSThread的类别中提供,并没有在NSObject协议中声明。 所以,如果你想调用它,那么你需要声明你的types为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 

现在,让我们稍后通过协议。 假设你正在编写generics代码,你只是想知道你给的对象是否符合协议,如果是的话,就调用一个方法。 就像是…

 @interface Bar : NSObject @property (nonatomic, weak) NSObject<ReloadChatViewControllerDelegate> *refreshViewControllerDelegate; - (void)blarg; @end 

现在,Bar类提供了一个委托属性,所以它可以给一些对象来帮助它做一些工作。 但是,该委托对象必须至less是一个NSObject ,并符合ReloadChatViewControllerDelegate协议。

现在,ObjC(和C)是相当宽容的,所以你可以强制一个对象成为你想要的任何types,但是你应该得到这个崩溃。 现在,当blarg时,通知代表做一些工作。

由于委托的属性types已经表明它符合给定的协议,所以不需要检查一致性。 我们可以调用委托方法。 请注意,我们必须看看对象是否实现了任何可选的协议方法。

 @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(或其他types)。

 @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]; 

你需要像这样声明你的委托:

 @property (nonatomic, weak) IBOutlet id<ReloadViewControllerDelegate> delegate; 

该id将工作,但通过使用<>,您可以确保您分配的委托实际上正在实施该协议,您可能仍然必须确保它响应select器,但只有当某些方法被声明为

 @optional 

确保你综合它,最重要的是确保你设置它,而不是零。

你得到一个警告,因为你input你的委托作为一个id 。 一个id是一个genericstypes,这意味着编译器不知道什么方法或属性可用。 为了删除您的警告,请将您的委托声明为NSObject:

 @property (nonatomic, retain) NSObject <ReloadViewControllerDelegate> *refreshViewControllerDelegate; 

通过声明NSObject,编译器现在知道NSObject所有的方法,然后可以调用:

 -performSelectorOnMainThread:withObject:waitUntilDone: 

在您的代表没有警告。 祝你好运!

尝试这个:

 @protocol ReloadViewControllerDelegate <NSObject> -(void) refreshViewController:(NSString *)result; @end @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (weak) id <ReloadViewControllerDelegate>refreshViewControllerDelegate; @end 

在AppDelegate.m中

 @implementation AppDelegate @synthesize window, refreshViewControllerDelegate; ... 

这里Tab4ViewController是类的名字。

  if ([Tab4ViewController conformsToProtocol:@protocol(ReloadViewControllerDelegate)]) { [refreshViewControllerDelegate performSelectorOnMainThread:@selector(refreshViewController:) withObject:@"YES" waitUntilDone:NO]; } ... @end #import "AppDelegate.h" @interface Tab4ViewController<ReloadViewControllerDelegate> ... @end @implementation Tab4ViewController ... appDelegate.refreshViewControllerDelegate = self; ... @end